update light
This commit is contained in:
@@ -1,21 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.AddressableAssets.ResourceLocators;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.U2D;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
/// <summary>
|
||||
/// Scene game (Bootstrap): chờ gate chỉ khi <see cref="GameContentBootstrap"/> cùng scene.
|
||||
/// Nếu đã chạy scene GameContentBootstrap trước → <see cref="GameContentBootstrapSession.IsContentReady"/>.
|
||||
/// Scene Bootstrap (index 1): Addressables luôn được init thẳng vì
|
||||
/// <see cref="GameContentBootstrap"/> đã chạy xong ở scene 0 (<see cref="GameContentBootstrapSession.IsContentReady"/> = true).
|
||||
/// </summary>
|
||||
[DefaultExecutionOrder(-1990)]
|
||||
public class AddressableManager : MonoSingleton<AddressableManager>
|
||||
@@ -38,14 +36,6 @@ namespace BrewMonster.Scripts
|
||||
private Dictionary<string, float> _releaseAssetTimestamps = new();
|
||||
[SerializeField]private float _releaseAssetTimeout = 10f;
|
||||
|
||||
[Header("Bootstrap gate")]
|
||||
[Tooltip("Max seconds to wait for GameContentBootstrap before initializing Addressables anyway.")]
|
||||
[SerializeField]
|
||||
float _bootstrapGateWaitTimeoutSeconds = 50f;
|
||||
|
||||
[SerializeField]
|
||||
bool _verboseBootstrapWaitDebug = true;
|
||||
|
||||
public event Action OnDispose;
|
||||
|
||||
/// <summary>Get the count of currently loaded assets.</summary>
|
||||
@@ -65,13 +55,7 @@ namespace BrewMonster.Scripts
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
if (_verboseBootstrapWaitDebug)
|
||||
{
|
||||
Debug.Log(
|
||||
$"[Cuong] AddressableManager: Awake | id={GetInstanceID()} scene={SceneManager.GetActiveScene().name} " +
|
||||
$"frame={Time.frameCount} bootstrapGate={GameContentBootstrap.GetGateDebugState()}");
|
||||
}
|
||||
|
||||
Debug.Log($"[Cuong] AddressableManager: Awake | id={GetInstanceID()} frame={Time.frameCount}");
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
@@ -80,35 +64,11 @@ namespace BrewMonster.Scripts
|
||||
base.Initialize();
|
||||
_isInitialized = false;
|
||||
_initializationTcs = new UniTaskCompletionSource();
|
||||
StartAddressablesInitAfterBootstrapGate().Forget();
|
||||
StartAddressablesInitAsync().Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for <see cref="GameContentBootstrap"/> (version HTTP + optional URL rewrite) when that gate is active.
|
||||
/// </summary>
|
||||
async UniTaskVoid StartAddressablesInitAfterBootstrapGate()
|
||||
async UniTaskVoid StartAddressablesInitAsync()
|
||||
{
|
||||
if (GameContentBootstrapSession.IsContentReady || AddressablesInitService.IsInitialized)
|
||||
{
|
||||
Debug.Log(
|
||||
$"[Cuong] AddressableManager: Content bootstrap đã chạy ở scene trước — init Addressables (scene={SceneManager.GetActiveScene().name}).");
|
||||
}
|
||||
else
|
||||
{
|
||||
var gateState = GameContentBootstrap.GetGateDebugState();
|
||||
Debug.Log(
|
||||
$"[Cuong] AddressableManager: Đang chờ GameContentBootstrap (version / URL rewrite)... | " +
|
||||
$"id={GetInstanceID()} scene={SceneManager.GetActiveScene().name} gate={gateState}");
|
||||
|
||||
var waited = await WaitForBootstrapGateWithTimeoutAsync();
|
||||
if (!waited)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"[Cuong] AddressableManager: Bootstrap gate timeout ({_bootstrapGateWaitTimeoutSeconds:F0}s) — " +
|
||||
"InitializeAsync anyway. Nên dùng scene GameContentBootstrap riêng (index 0).");
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log("[Cuong] AddressableManager: Đang InitializeAsync Addressables...");
|
||||
try
|
||||
{
|
||||
@@ -125,21 +85,6 @@ namespace BrewMonster.Scripts
|
||||
}
|
||||
}
|
||||
|
||||
async UniTask<bool> WaitForBootstrapGateWithTimeoutAsync()
|
||||
{
|
||||
var timeoutSec = Mathf.Max(5f, _bootstrapGateWaitTimeoutSeconds);
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSec));
|
||||
try
|
||||
{
|
||||
await GameContentBootstrap.WaitForPreAddressablesSetupIfAnyAsync(cts.Token);
|
||||
return true;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#region Unity lifecycle
|
||||
private List<string> _assetToForceRelease = new();
|
||||
private void Update()
|
||||
|
||||
@@ -34,9 +34,12 @@ namespace BrewMonster.Network
|
||||
shiftedUnix = 0L;
|
||||
var serverLocalUtc = DateTimeOffset.FromUnixTimeSeconds(shiftedUnix).UtcDateTime;
|
||||
int nTimeInDay = serverLocalUtc.Hour * 3600 + serverLocalUtc.Minute * 60 + serverLocalUtc.Second;
|
||||
float phase = nTimeInDay / (4f * 3600f);
|
||||
SetTimeOfTheDay(phase);
|
||||
BMLogger.Log($"[Cuong] SyncSunMoon server-local {serverLocalUtc.Hour:D2}:{serverLocalUtc.Minute:D2}:{serverLocalUtc.Second:D2}, phase={phase}");
|
||||
// C++ formula: nTimeInDay / (4f*3600f) — drives 4h sun/moon animation cycle (matches EC_Game.cpp SetServerTime)
|
||||
float phase4h = nTimeInDay / (4f * 3600f);
|
||||
// Real 24h phase: maps server time directly to [0,1) — used for nightControl shader (noon=day, midnight=night)
|
||||
float phase24h = nTimeInDay / (24f * 3600f);
|
||||
SetTimeOfTheDayFull(phase4h, phase24h);
|
||||
BMLogger.Log($"[Cuong] SyncSunMoon server-local {serverLocalUtc.Hour:D2}:{serverLocalUtc.Minute:D2}:{serverLocalUtc.Second:D2}, phase4h={phase4h:F3} phase24h={phase24h:F3}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -54,6 +57,18 @@ namespace BrewMonster.Network
|
||||
BMLogger.Log($"[Cuong] EC_Game.SetTimeOfTheDay vTime(in)={vTime}, m_vTimeOfTheDay={sunMoon.m_vTimeOfTheDay}");
|
||||
}
|
||||
|
||||
static void SetTimeOfTheDayFull(float phase4h, float phase24h)
|
||||
{
|
||||
var sunMoon = CECSunMoon.Instance;
|
||||
if (sunMoon == null)
|
||||
{
|
||||
BMLogger.LogWarning("[Cuong] EC_Game.SetTimeOfTheDayFull: CECSunMoon.Instance is null.");
|
||||
return;
|
||||
}
|
||||
sunMoon.SetTimeOfTheDayFull(phase4h, phase24h);
|
||||
BMLogger.Log($"[Cuong] EC_Game.SetTimeOfTheDayFull phase4h={phase4h:F3} phase24h={phase24h:F3}, m_vTimeOfTheDay={sunMoon.m_vTimeOfTheDay:F3} m_vRealPhase={sunMoon.m_vRealPhase:F3}");
|
||||
}
|
||||
|
||||
// 设置时间误差 // Set time error
|
||||
public static void SetServerTime(int iSevTime, int iTimeZoneBias)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace BrewMonster.Scripts
|
||||
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
|
||||
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
|
||||
|
||||
@@ -28,9 +29,15 @@ namespace BrewMonster.Scripts
|
||||
|
||||
public void Update()
|
||||
{
|
||||
m_vTimeOfTheDay += Time.deltaTime / 3600.0 / 24.0 * TIME_SCALE;
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -40,6 +47,7 @@ namespace BrewMonster.Scripts
|
||||
|
||||
/// <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)
|
||||
{
|
||||
@@ -52,14 +60,34 @@ namespace BrewMonster.Scripts
|
||||
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;
|
||||
|
||||
// update day night factor — same branches as PC EC_SunMoon.cpp UpdateWithTime (lines 894–918)
|
||||
// m_fDNFactor — 4h cycle phase, same as C++ EC_SunMoon::UpdateWithTime lines 894-918
|
||||
if (v < NIGHT_DAY_START)
|
||||
{
|
||||
m_fDNFactor = 1.0f;
|
||||
@@ -87,7 +115,22 @@ namespace BrewMonster.Scripts
|
||||
m_fDNFactorDest = 1.0f;
|
||||
}
|
||||
|
||||
_globalShaderVariables?.Apply(m_fDNFactor);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user