using System.Collections; using System.Collections.Generic; using System.Linq; using Cysharp.Threading.Tasks; using Framework; using PhxhSDK; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; namespace Gameplay.SubSystems { public class GameSceneManager : Singlenton { public enum EnumScene { GameStart, // 登录场景 GameMain, // 主场景 GameLevel // 关卡(战场)场景 } public const string SCENE_PREFIX = "Assets/Scenes/"; public const string START_SCENE_NAME = "StartScene"; public const string LEVEL_SCENE_NAME = "LevelScene"; public const string MAIN_SCENE_NAME = "MainScene"; public const string SCENE_SUFFIX = ".unity"; private Dictionary> _sceneOpDic = new(); public async UniTask ChangeScene(EnumScene enumScene) { string sceneName = SCENE_PREFIX; switch (enumScene) { case EnumScene.GameStart: sceneName += START_SCENE_NAME; break; case EnumScene.GameMain: sceneName += MAIN_SCENE_NAME; break; case EnumScene.GameLevel: sceneName += LEVEL_SCENE_NAME; break; default: DebugUtil.LogError("{0}.ChangeScene, {1} has no scene name matched", GetType(), enumScene); sceneName += START_SCENE_NAME; break; } sceneName += SCENE_SUFFIX; await LoadSceneAsync(sceneName); } public async UniTask LoadSceneAsync(string scenePath, LoadSceneMode mode = LoadSceneMode.Single) { if (string.IsNullOrEmpty(scenePath)) { DebugUtil.LogError($"ScenePath is null!"); return; } if(mode == LoadSceneMode.Single) _sceneOpDic.Clear(); if (!_sceneOpDic.TryGetValue(scenePath, out var op)) { op = Addressables.LoadSceneAsync(scenePath, mode); _sceneOpDic.Add(scenePath, op); } await op.ToUniTask(); } public async UniTask UnLoadSceneAsync(string scenePath) { if (string.IsNullOrEmpty(scenePath)) { DebugUtil.LogError($"ScenePath is null!"); return; } if (!_sceneOpDic.TryGetValue(scenePath, out var op)) { Debug.LogError($"该场景没有被加载过 scenePath:{scenePath}"); return; } _sceneOpDic.Remove(scenePath); await Addressables.UnloadSceneAsync(op).ToUniTask(); } public float GetSceneLoadingProgress(string scenePath) { if (_sceneOpDic.TryGetValue(scenePath, out var op)) { return op.PercentComplete; } return 0; } } }