# WorldTime (P9) —— 昼夜循环:GC_TIME 的服务器时钟 → 太阳角度 + 光色 + 环境色。 # # var wt := preload("res://world/world_time.gd").new() # add_child(wt) # wt.setup(m2client, sun_light, environment) # environment 可空 # # GC_TIME 给的是 unix 秒。本地按 delta 累加,得到「日内秒」(0..86400)。 # 06:00 日出、12:00 正午、18:00 日落、0:00 午夜。太阳 pitch 随之走。 extends Node const DAY := 86400.0 const CYCLE_SCALE := 1.0 # >1 加速昼夜(调试用) var client: Node var sun: DirectionalLight3D var env: Environment var _epoch := 0.0 # 最近一次 GC_TIME 的服务器 unix 秒 var _since := 0.0 # 收到后本地经过的秒 var _have_time := false func setup(m2client: Node, sun_light: DirectionalLight3D, environment: Environment = null) -> void: client = m2client sun = sun_light env = environment if client and client.has_signal("time_changed"): client.time_changed.connect(_on_time) if client and client.has_method("get_server_time"): var t: int = client.get_server_time() if t > 0: _on_time(t) func _on_time(server_epoch: int) -> void: _epoch = float(server_epoch) _since = 0.0 _have_time = true # 当前日内秒(0..86400)。没有 GC_TIME 时固定用「正午」——不要跟着玩家的系统钟 # 走到半夜把整个场景变黑(那不是 m2dev-client-main 的行为)。 const DEFAULT_NOON := 43200.0 func seconds_of_day() -> float: if not _have_time: return DEFAULT_NOON return fmod((_epoch + _since) * CYCLE_SCALE, DAY) # 0 = 午夜, 0.25 = 日出, 0.5 = 正午, 0.75 = 日落 func day_fraction() -> float: return seconds_of_day() / DAY func _process(delta: float) -> void: _since += delta if sun == null: return var f := day_fraction() # 太阳高度角:正午(0.5)最高 ~ -85°(朝下),午夜最低 ~ +85°(朝上,被地平线挡) var elevation := sin((f - 0.25) * TAU) * 80.0 # -80..80 var azimuth := lerpf(40.0, 220.0, f) sun.rotation = Vector3(deg_to_rad(-elevation), deg_to_rad(azimuth), 0.0) # 光照强度 & 颜色:白天暖白,黄昏偏橙,夜里近黑冷蓝 var daylight := clampf(sin((f - 0.25) * TAU) * 1.4 + 0.3, 0.0, 1.0) sun.light_energy = lerpf(0.03, 1.15, daylight) var warm := Color(1.0, 0.55, 0.30) var noon := Color(1.0, 0.97, 0.90) var night := Color(0.35, 0.42, 0.65) if daylight < 0.35: sun.light_color = night.lerp(warm, daylight / 0.35) else: sun.light_color = warm.lerp(noon, (daylight - 0.35) / 0.65) if env: env.ambient_light_energy = lerpf(0.12, 0.6, daylight) env.ambient_light_color = Color(0.16, 0.19, 0.30).lerp(Color(0.5, 0.55, 0.62), daylight) if env.background_mode == Environment.BG_COLOR: env.background_color = Color(0.03, 0.04, 0.09).lerp(Color(0.55, 0.62, 0.72), daylight)