using System;
|
using System.IO;
|
using Cysharp.Threading.Tasks;
|
using UnityEngine;
|
using UnityEngine.SceneManagement;
|
using ProjSG.Resource;
|
using YooAsset;
|
|
public enum StageName
|
{
|
Login,
|
Game,
|
}
|
|
public class StageManager : Singleton<StageManager>, IManager
|
{
|
public StageName currentStage;
|
|
public Action AfterLoadingGameScene;
|
|
public Action BeforeLoadingGameScene;
|
|
// public Action OnSwitchAccount;
|
private LaunchWinData launchWinData = null;
|
|
public UniTask Init()
|
{
|
UIManager.Instance.OnCloseWindow += OnCloseWindow;
|
return UniTask.CompletedTask;
|
}
|
|
public void Release()
|
{
|
AfterLoadingGameScene = null;
|
BeforeLoadingGameScene = null;
|
UIManager.Instance.OnCloseWindow -= OnCloseWindow;
|
}
|
|
public async UniTaskVoid ToLoginScene()
|
{
|
UIManager.Instance.DestroyAllUI();
|
|
// US3: Show loading screen FIRST, then load resources with progress
|
LoadingWin loadingWin = await UIManager.Instance.OpenWindowAsync<LoadingWin>();
|
InitLoadingWinData(loadingWin);
|
|
// Phase 1 (0% ~ 50%): Scene loading
|
if (AssetSource.isUseAssetBundle)
|
{
|
var handle = YooAssetService.Instance.BeginLoadScene("Assets/ResourcesOut/Scenes/Login.unity", LoadSceneMode.Single, LocalPhysicsMode.None, true);
|
while (!handle.IsDone)
|
{
|
if (handle.Progress >= 0.9f)
|
handle.UnSuspend();
|
loadingWin.SetProgress(handle.Progress * 0.5f);
|
await UniTask.Yield();
|
}
|
}
|
else
|
{
|
var asyncOp = SceneManager.LoadSceneAsync("Login");
|
asyncOp.allowSceneActivation = false;
|
while (!asyncOp.isDone)
|
{
|
if (asyncOp.progress >= 0.9f)
|
asyncOp.allowSceneActivation = true;
|
loadingWin.SetProgress(asyncOp.progress * 0.5f);
|
await UniTask.Yield();
|
}
|
}
|
|
// Phase 2 (50% ~ 100%): Manager initialization
|
await WaitForManagerProgress(loadingWin, 0.5f, 1.0f,
|
ConfigManager.Instance.GetLoadingProgress, Main.InitManagers);
|
|
loadingWin.SetProgress(1f, true);
|
await UniTask.Delay(TimeSpan.FromSeconds(0.5f));
|
loadingWin.CloseWindow();
|
|
Main.OnSwitchToLoginScene();
|
|
currentStage = StageName.Login;
|
|
UIManager.Instance.OpenWindowAsync<LaunchBackGroundWin>().ContinueWith(s => {
|
UIManager.Instance.OpenWindowAsync<LoginWin>().Forget();
|
DumpLoginSceneDiagnostics("ToLoginScene open triggered").ContinueWith(() => {
|
if (VersionUtility.Instance.NeedDownAsset() && !AssetVersionUtility.hasDownLoadFullAsset)
|
{
|
DownloadHotMgr.Instance.ClearDownloadCache();
|
InGameDownLoad.Instance.inGameDownLoadAllow = true;
|
InGameDownLoad.Instance.TryDownLoad(InGameDownLoad.Dominant.None);
|
}
|
}).Forget();
|
}).Forget();
|
|
|
|
}
|
|
// 返回登录界面 如断线
|
public async UniTaskVoid ReturnToLoginScene()
|
{
|
UIManager.Instance.DestroyAllUI();
|
|
if (AssetSource.isUseAssetBundle)
|
await YooAssetService.Instance.LoadSceneAsync("Assets/ResourcesOut/Scenes/Login.unity");
|
else
|
await SceneManager.LoadSceneAsync("Login");
|
|
Main.OnSwitchToLoginScene();
|
currentStage = StageName.Login;
|
|
UIManager.Instance.OpenWindowAsync<LaunchBackGroundWin>().ContinueWith(s => {
|
UIManager.Instance.OpenWindowAsync<LoginWin>().Forget();
|
DumpLoginSceneDiagnostics("ToLoginScene open triggered").ContinueWith(() => {
|
if (ServerForceExitHintWin.reason != 0)
|
{
|
UIManager.Instance.OpenWindowAsync<ServerForceExitHintWin>().Forget();
|
}
|
// SoundPlayer.Instance.StopBackGroundMusic();
|
SoundPlayer.Instance.PlayLoginMusic();
|
}).Forget();
|
}).Forget();
|
}
|
|
private async UniTask DumpLoginSceneDiagnostics(string context)
|
{
|
await UniTask.DelayFrame(2);
|
UIManager.Instance.DumpUIDiagnostics(context + " after 2 frames");
|
await UniTask.DelayFrame(30);
|
UIManager.Instance.DumpUIDiagnostics(context + " after 32 frames");
|
}
|
|
protected float GetManagerRequestDataProgress()
|
{
|
if (Main.managers.Count == 0)
|
{
|
return 1f;
|
}
|
|
int count = 0;
|
|
for (int i = 0; i < Main.managers.Count; i++)
|
{
|
var manager = Main.managers[i];
|
|
if (manager.IsNessaryDataReady())
|
{
|
count++;
|
}
|
}
|
|
return ((float)count) / ((float)Main.managers.Count);
|
}
|
|
public async UniTaskVoid ToGameScene()
|
{
|
UIManager.Instance.DestroyAllUI();
|
|
BeforeLoadingGameScene?.Invoke();
|
|
// US3: Show loading screen FIRST, then load resources with progress
|
LoadingWin loadingWin = await UIManager.Instance.OpenWindowAsync<LoadingWin>();
|
InitLoadingWinData(loadingWin);
|
|
SoundPlayer.Instance.StopBackGroundMusic();
|
|
// Phase 1 (0% ~ 50%): Scene loading
|
if (AssetSource.isUseAssetBundle)
|
{
|
var handle = YooAssetService.Instance.BeginLoadScene("Assets/ResourcesOut/Scenes/Game.unity", LoadSceneMode.Single, LocalPhysicsMode.None, true);
|
while (!handle.IsDone)
|
{
|
if (handle.Progress >= 0.9f)
|
handle.UnSuspend();
|
loadingWin.SetProgress(handle.Progress * 0.5f);
|
await UniTask.Yield();
|
}
|
}
|
else
|
{
|
var asyncOp = SceneManager.LoadSceneAsync("Game");
|
asyncOp.allowSceneActivation = false;
|
while (!asyncOp.isDone)
|
{
|
if (asyncOp.progress >= 0.9f)
|
asyncOp.allowSceneActivation = true;
|
loadingWin.SetProgress(asyncOp.progress * 0.5f);
|
await UniTask.Yield();
|
}
|
}
|
|
// Phase 2 (50% ~ 100%): Manager data ready
|
await WaitForManagerProgress(loadingWin, 0.5f, 1.0f,
|
() => (DTC0403_tagPlayerLoginLoadOK.finishedLogin ? .5f : 0f) + GetManagerRequestDataProgress() * .5f);
|
|
loadingWin.SetProgress(1f, true);
|
await UniTask.Delay(TimeSpan.FromSeconds(0.5f));
|
loadingWin.CloseWindow();
|
|
// 加载初始化数据完成
|
currentStage = StageName.Game;
|
|
Main.OnEnterGameScene();
|
|
AfterLoadingGameScene?.Invoke();
|
|
UIManager.Instance.OpenWindowAsync<MainWin>().Forget();
|
|
//游戏内日志关闭
|
#if !UNITY_EDITOR
|
if (File.Exists(Directory.GetParent(Application.persistentDataPath) + "/Debug") ||
|
LocalSave.GetString("#@#BrancH") != string.Empty)
|
{
|
Debug.unityLogger.logEnabled = true;
|
}
|
else
|
{
|
Debug.unityLogger.logEnabled = false;
|
}
|
|
#endif
|
}
|
|
protected async UniTask OnLoading(AsyncOperation asyncOperation, Func<float> getLoadingProgress, Func<UniTask> anthorTask = null)
|
{
|
asyncOperation.allowSceneActivation = false;
|
|
LoadingWin loadingWin = await UIManager.Instance.OpenWindowAsync<LoadingWin>();
|
InitLoadingWinData(loadingWin);
|
|
while (!asyncOperation.isDone)
|
{
|
if (asyncOperation.progress >= 0.9f)
|
{
|
asyncOperation.allowSceneActivation = true;
|
}
|
|
loadingWin.SetProgress(asyncOperation.progress * 0.5f + getLoadingProgress() * 0.5f);
|
|
await UniTask.Yield();
|
}
|
|
float managerProgress = getLoadingProgress();
|
|
while (managerProgress < 1f)
|
{
|
loadingWin.SetProgress(asyncOperation.progress * 0.5f + managerProgress * 0.5f);
|
|
await UniTask.Yield();
|
|
managerProgress = getLoadingProgress();
|
}
|
|
if (anthorTask != null)
|
{
|
await anthorTask();
|
}
|
|
loadingWin.SetProgress(1f, true);
|
|
await UniTask.Delay(TimeSpan.FromSeconds(0.5f));
|
|
loadingWin.CloseWindow();
|
}
|
|
/// <summary>
|
/// US3: 等待Manager初始化进度并更新LoadingWin。
|
/// </summary>
|
private async UniTask WaitForManagerProgress(LoadingWin loadingWin, float startPct, float endPct,
|
Func<float> getProgress, Func<UniTask> extraTask = null)
|
{
|
float managerProgress = getProgress();
|
|
while (managerProgress < 1f)
|
{
|
loadingWin.SetProgress(startPct + managerProgress * (endPct - startPct));
|
await UniTask.Yield();
|
managerProgress = getProgress();
|
}
|
|
if (extraTask != null)
|
{
|
await extraTask();
|
}
|
}
|
|
/// <summary>
|
/// US3: 初始化 LoadingWin 数据(从 LaunchWin 继承背景等)。
|
/// </summary>
|
private void InitLoadingWinData(LoadingWin loadingWin)
|
{
|
LaunchWin launchWin = UIManager.Instance.GetUI<LaunchWin>();
|
if (launchWin != null && launchWin.IsActive() && launchWinData == null)
|
{
|
launchWinData = launchWin.GetData();
|
}
|
|
if (launchWinData != null)
|
{
|
loadingWin.SetData(launchWinData);
|
launchWinData = null;
|
}
|
}
|
|
private void OnCloseWindow(UIBase closeUI)
|
{
|
if (closeUI is LaunchWin)
|
{
|
launchWinData = (closeUI as LaunchWin).GetData();
|
}
|
}
|
}
|