using UnityEngine; // using UniTask; namespace BrewMonster.Scripts { public class CECSunMoon : MonoSingleton { private const float TIME_SCALE = 6f; private const float NIGHT_DAY_START = (3.0f / 24.0f); private const float NIGHT_DAY_END = (7.0f / 24.0f); private const float DAY_NIGHT_START = (18.0f / 24.0f); private const float DAY_NIGHT_END = (21.0f / 24.0f); public double m_vTimeOfTheDay; // time of the day 0.0f means 00:00, 1.0f means 24:00 (4h-cycle phase, matches C++ CECSunMoon) public double m_vRealPhase; // 真实服务器时间对应的24h相位(用于 nightControl shader)// real 24h phase from server time, used for nightControl shader (not the 4h-wrapped cycle) public float m_fDNFactor; // day or night factor public float m_fDNFactorDest; // day or night factor dest [SerializeField] GlobalShaderVariableSetting _globalShaderVariables; protected override void Initialize() { base.Initialize(); // keep this alive when scene is loaded DontDestroyOnLoad(gameObject); RefreshDayNightFactorsFromPhase(); } public void Update() { double advance = Time.deltaTime / 3600.0 / 24.0; // 4h cycle — same as C++ Tick(): drives sun/moon visual animation m_vTimeOfTheDay += advance * TIME_SCALE; while (m_vTimeOfTheDay > 1.0) m_vTimeOfTheDay -= 1.0; // 24h real-time phase — used for nightControl shader (not TIME_SCALE-sped-up) m_vRealPhase += advance; while (m_vRealPhase > 1.0) m_vRealPhase -= 1.0; RefreshDayNightFactorsFromPhase(); } public float GetTimeOfTheDay() => (float)m_vTimeOfTheDay; public float GetDNFactor() => m_fDNFactor; public float GetDNFactorDest() => m_fDNFactorDest; /// /// 设置一天中的时刻(与 PC 版 CECSunMoon::SetTimeOfTheDay 对齐) // Set time-of-day phase [0,1), aligned with PC CECSunMoon::SetTimeOfTheDay /// 仅设置4h动画相位;用 SetTimeOfTheDayFull 同时设置真实24h相位 // Sets 4h animation phase only; use SetTimeOfTheDayFull to also set the real 24h phase /// public bool SetTimeOfTheDay(float vTime) { while (vTime < 0f) vTime += 1f; while (vTime > 1f) vTime -= 1f; m_vTimeOfTheDay = vTime; RefreshDayNightFactorsFromPhase(); return true; } /// /// 同时设置4h动画相位(C++公式)和24h真实相位(shader nightControl用) // Set both the 4h animation phase (C++ formula) and the real 24h phase (for shader nightControl) /// /// nTimeInDay / (4f*3600f) — wrap to [0,1), drives sun/moon animation /// nTimeInDay / (24f*3600f) — [0,1), drives nightControl shader (0=day 1=night based on real server time) public bool SetTimeOfTheDayFull(float phase4h, float phase24h) { while (phase4h < 0f) phase4h += 1f; while (phase4h > 1f) phase4h -= 1f; m_vTimeOfTheDay = phase4h; phase24h = Mathf.Clamp01(phase24h); m_vRealPhase = phase24h; RefreshDayNightFactorsFromPhase(); return true; } /// /// PC EC_SunMoon::UpdateWithTime 中昼夜因子段(供 minimap 与场景一致) // DN factor block from PC EC_SunMoon::UpdateWithTime /// m_fDNFactor 由4h相位驱动(与C++一致,用于太阳/月亮视觉); nightControl 由24h真实相位驱动(shader正确反映服务器白天/黑夜) /// m_fDNFactor is driven by the 4h phase (C++ compatible, for sun/moon visuals); nightControl is driven by the real 24h phase (shader correctly reflects server day/night) /// void RefreshDayNightFactorsFromPhase() { float v = (float)m_vTimeOfTheDay; // m_fDNFactor — 4h cycle phase, same as C++ EC_SunMoon::UpdateWithTime lines 894-918 if (v < NIGHT_DAY_START) { m_fDNFactor = 1.0f; m_fDNFactorDest = 1.0f; } else if (v < NIGHT_DAY_END) { m_fDNFactor = 1.0f - (v - NIGHT_DAY_START) / (NIGHT_DAY_END - NIGHT_DAY_START); m_fDNFactorDest = 0.0f; } else if (m_vTimeOfTheDay < DAY_NIGHT_START) { // PC 使用 m_vTimeOfTheDay 与 DAY_NIGHT_START 比较 // PC compares m_vTimeOfTheDay to DAY_NIGHT_START (see EC_SunMoon.cpp) m_fDNFactor = 0.0f; m_fDNFactorDest = 0.0f; } else if (v < DAY_NIGHT_END) { m_fDNFactor = (v - DAY_NIGHT_START) / (DAY_NIGHT_END - DAY_NIGHT_START); m_fDNFactorDest = 1.0f; } else { m_fDNFactor = 1.0f; m_fDNFactorDest = 1.0f; } // nightControl shader — driven by m_vRealPhase (24h real server time, 0=day 1=night) // 用真实24h相位计算 nightControl,确保正午=白天(0),午夜=黑夜(1),不受4h周期wrap影响 // Real 24h phase ensures noon=day(0), midnight=night(1), unaffected by 4h cycle wrapping _globalShaderVariables?.Apply(ComputeNightControlFromRealPhase((float)m_vRealPhase)); } /// /// 用24h真实相位计算 nightControl(与相同阈值,但基于实际服务器时间) // Compute nightControl from real 24h phase using same thresholds /// static float ComputeNightControlFromRealPhase(float r) { if (r < NIGHT_DAY_START) return 1.0f; if (r < NIGHT_DAY_END) return 1.0f - (r - NIGHT_DAY_START) / (NIGHT_DAY_END - NIGHT_DAY_START); if (r < DAY_NIGHT_START) return 0.0f; if (r < DAY_NIGHT_END) return (r - DAY_NIGHT_START) / (DAY_NIGHT_END - DAY_NIGHT_START); return 1.0f; } } }