using Cysharp.Threading.Tasks; using PhxhSDK; using PhxhSDK.Res; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; namespace Gameplay.SubSystems { /// /// 游戏场景的底层逻辑 /// public class GameSceneManager : Singlenton { /// /// 空场景名 /// private const string EMPTY_SCENE = "Empty.unity"; /// /// 空场景路径 /// private readonly string EMPTY_SCENE_PATH = $"Assets/Scenes/{EMPTY_SCENE}"; /// /// 是否使用低品质场景 /// private bool useLowScene; /// /// 场景加载器 /// private readonly ISceneLoader sceneLoader; /// /// 加载中的场景列表 /// private readonly HashSet setLoadingScene = new(); /// /// 等待卸载的场景 /// private string waitUnloadScene; public GameSceneManager() { #if UNITY_EDITOR if (!Application.isPlaying) { sceneLoader = new SceneLoader_Fake(); return; } #endif #if USE_YOO sceneLoader = new SceneLoader_YooAsset(); #else _sceneLoader = new SceneLoader_Addressables(); #endif } public void SetSceneLoadingSetting(bool isUseLowScene) { useLowScene = isUseLowScene; } public async UniTask LoadSceneAsync(string scenePath, LoadSceneMode mode = LoadSceneMode.Single) { string realScenePath = GetPostProcessedScenePath(scenePath); // 真实加载路径 if (string.IsNullOrEmpty(realScenePath)) { DebugUtil.LogError($"转换后的场景路径为空!无法加载"); return null; } if (!setLoadingScene.Add(realScenePath)) { DebugUtil.LogError($"上一个相同场景还在加载中,请等待加载完成后再次加载:{realScenePath}"); return null; } PhxhSDK.Res.SceneHandle sceneHandle = null; if (!sceneLoader.IsExistScene(realScenePath)) { if (LoadSceneMode.Single == mode) { // 先切换到Empty场景 await sceneLoader.LoadSceneAsync(EMPTY_SCENE_PATH, true); await Resources.UnloadUnusedAssets(); } sceneHandle = await sceneLoader.LoadSceneAsync(realScenePath, false, mode); } setLoadingScene.Remove(realScenePath); if (!string.IsNullOrEmpty(waitUnloadScene)) { if (scenePath == waitUnloadScene) { DebugUtil.Log($"等待卸载的场景和当前加载的场景一样,不卸载:{waitUnloadScene}"); waitUnloadScene = null; } else { DebugUtil.Log($"卸载之前的场景:{waitUnloadScene}"); await UnLoadSceneAsync(waitUnloadScene); waitUnloadScene = null; } } if (mode == LoadSceneMode.Single) await sceneLoader.UnAllLoadSceneAsync(realScenePath); return sceneHandle; } public async UniTask UnLoadSceneAsync(string scenePath) { string realScenePath = GetPostProcessedScenePath(scenePath); if (string.IsNullOrEmpty(realScenePath)) { DebugUtil.LogError($"卸载失败,路径:{realScenePath}"); return; } await sceneLoader.UnLoadSceneAsync(realScenePath); if (null != scenePath && string.Empty != scenePath) waitUnloadScene = scenePath; } /// /// 返回场景加载的进度 /// /// /// 0-100的浮点数 public float GetSceneLoadingProgress(string scenePath) { return sceneLoader.GetSceneLoadingProgress(GetPostProcessedScenePath(scenePath)); } /// /// 获取后处理场景路径 /// /// /// private string GetPostProcessedScenePath(string scenePath) { if (scenePath.Equals(EMPTY_SCENE)) return scenePath; if (useLowScene && !scenePath.Contains("_low")) { string lowScenePath = scenePath.Replace(".unity", "_low.unity"); if (PostProcessData.Instance.TryGetPostProcessedPath(lowScenePath, out string finalLowScenePath)) return finalLowScenePath; } bool isFind = PostProcessData.Instance.TryGetPostProcessedPath(scenePath, out string finalScenePath); if (!isFind) DebugUtil.LogError($"未找到场景的后处理:{scenePath}"); return finalScenePath; } } }