using System; using System.IO; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.SceneManagement; using ProjSG.Resource; public enum StageName { Login, Game, } public class StageManager : Singleton, IManager { public StageName currentStage; public Action AfterLoadingGameScene; public Action BeforeLoadingGameScene; // public Action OnSwitchAccount; private LaunchWinData launchWinData = null; public void Init() { UIManager.Instance.OnCloseWindow += OnCloseWindow; } 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 = UIManager.Instance.OpenWindow(); InitLoadingWinData(loadingWin); // Phase 1 (0% ~ 30%): YooAsset resource preload if (AssetSource.isUseAssetBundle) { loadingWin.SetProgress(0.05f); await YooAssetService.Instance.LoadAllAssetsAsync("Assets/ResourcesOut/maps/Login"); loadingWin.SetProgress(0.3f); } // Phase 2 (30% ~ 60%): Scene loading AsyncOperation asyncOperation = SceneManager.LoadSceneAsync("Login"); asyncOperation.allowSceneActivation = false; while (!asyncOperation.isDone) { if (asyncOperation.progress >= 0.9f) { asyncOperation.allowSceneActivation = true; } loadingWin.SetProgress(0.3f + asyncOperation.progress * 0.3f); await UniTask.Yield(); } // Phase 3 (60% ~ 100%): Manager initialization await WaitForManagerProgress(loadingWin, 0.6f, 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.OpenWindow(); UIManager.Instance.OpenWindow(); if (VersionUtility.Instance.NeedDownAsset() && !AssetVersionUtility.hasDownLoadFullAsset) { DownloadHotMgr.Instance.ClearDownloadCache(); InGameDownLoad.Instance.inGameDownLoadAllow = true; InGameDownLoad.Instance.TryDownLoad(InGameDownLoad.Dominant.None); } } // 返回登录界面 如断线 public void ReturnToLoginScene() { UIManager.Instance.DestroyAllUI(); SceneManager.LoadSceneAsync("Login"); Main.OnSwitchToLoginScene(); currentStage = StageName.Login; UIManager.Instance.OpenWindow(); UIManager.Instance.OpenWindow(); if (ServerForceExitHintWin.reason != 0) { UIManager.Instance.OpenWindow(); } // SoundPlayer.Instance.StopBackGroundMusic(); SoundPlayer.Instance.PlayLoginMusic(); } 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 = UIManager.Instance.OpenWindow(); InitLoadingWinData(loadingWin); // Phase 1 (0% ~ 30%): YooAsset resource preload if (AssetSource.isUseAssetBundle) { loadingWin.SetProgress(0.05f); await YooAssetService.Instance.LoadAllAssetsAsync("Assets/ResourcesOut/maps/Game"); loadingWin.SetProgress(0.3f); } SoundPlayer.Instance.StopBackGroundMusic(); // Phase 2 (30% ~ 60%): Scene loading AsyncOperation asyncOperation = SceneManager.LoadSceneAsync("Game"); asyncOperation.allowSceneActivation = false; while (!asyncOperation.isDone) { if (asyncOperation.progress >= 0.9f) { asyncOperation.allowSceneActivation = true; } loadingWin.SetProgress(0.3f + asyncOperation.progress * 0.3f); await UniTask.Yield(); } // Phase 3 (60% ~ 100%): Manager data ready await WaitForManagerProgress(loadingWin, 0.6f, 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.OpenWindow(); //游戏内日志关闭 #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 getLoadingProgress, Func anthorTask = null) { asyncOperation.allowSceneActivation = false; LoadingWin loadingWin = UIManager.Instance.OpenWindow(); 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(); } /// /// US3: 等待Manager初始化进度并更新LoadingWin。 /// private async UniTask WaitForManagerProgress(LoadingWin loadingWin, float startPct, float endPct, Func getProgress, Func extraTask = null) { float managerProgress = getProgress(); while (managerProgress < 1f) { loadingWin.SetProgress(startPct + managerProgress * (endPct - startPct)); await UniTask.Yield(); managerProgress = getProgress(); } if (extraTask != null) { await extraTask(); } } /// /// US3: 初始化 LoadingWin 数据(从 LaunchWin 继承背景等)。 /// private void InitLoadingWinData(LoadingWin loadingWin) { LaunchWin launchWin = UIManager.Instance.GetUI(); 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(); } } }