137 lines
6.3 KiB
C#
137 lines
6.3 KiB
C#
using UnityEngine;
|
||
// using UniTask;
|
||
|
||
namespace BrewMonster.Scripts
|
||
{
|
||
public class CECSunMoon : MonoSingleton<CECSunMoon>
|
||
{
|
||
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;
|
||
|
||
/// <summary>
|
||
/// 设置一天中的时刻(与 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
|
||
/// </summary>
|
||
public bool SetTimeOfTheDay(float vTime)
|
||
{
|
||
while (vTime < 0f)
|
||
vTime += 1f;
|
||
while (vTime > 1f)
|
||
vTime -= 1f;
|
||
m_vTimeOfTheDay = vTime;
|
||
RefreshDayNightFactorsFromPhase();
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 同时设置4h动画相位(C++公式)和24h真实相位(shader nightControl用) // Set both the 4h animation phase (C++ formula) and the real 24h phase (for shader nightControl)
|
||
/// </summary>
|
||
/// <param name="phase4h">nTimeInDay / (4f*3600f) — wrap to [0,1), drives sun/moon animation</param>
|
||
/// <param name="phase24h">nTimeInDay / (24f*3600f) — [0,1), drives nightControl shader (0=day 1=night based on real server time)</param>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 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)
|
||
/// </summary>
|
||
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));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 用24h真实相位计算 nightControl(与相同阈值,但基于实际服务器时间) // Compute nightControl from real 24h phase using same thresholds
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
}
|