Files
2026-05-29 10:02:52 +07:00

137 lines
6.3 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}