using System.Collections; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; using BaseGames.Core.Events; namespace BaseGames.Core { /// /// Addressables 场景加载器。 /// 监听 EVT_SceneLoadRequest,Additive 加载指定场景,完成后发布 EVT_SceneLoaded。 /// 完整实现由 SceneService 包装调用。 /// [DefaultExecutionOrder(-950)] public class SceneLoader : MonoBehaviour { [Header("Event Channels - Listen")] [SerializeField] private SceneLoadRequestEventChannelSO _onSceneLoadRequest; [Header("Event Channels - Raise")] [SerializeField] private StringEventChannelSO _onSceneLoaded; private string _currentRoomScene; private AsyncOperationHandle _currentHandle; private readonly CompositeDisposable _subs = new(); private void OnEnable() { _onSceneLoadRequest?.Subscribe(HandleRequest).AddTo(_subs); } private void OnDisable() { _subs.Clear(); } private void HandleRequest(SceneLoadRequest request) => StartCoroutine(LoadSceneCoroutine(request)); private IEnumerator LoadSceneCoroutine(SceneLoadRequest request) { // 先加载新场景(Additive),成功后再卸载旧场景 // 顺序保证:若加载失败,旧场景仍保持可用,不会出现无场景的空状态 var loadOp = Addressables.LoadSceneAsync(request.SceneName, LoadSceneMode.Additive); yield return loadOp; if (loadOp.Status != AsyncOperationStatus.Succeeded) { Debug.LogError($"[SceneLoader] 加载场景失败:{request.SceneName}(旧场景保持不变)"); yield break; } // 新场景加载成功,再卸载旧场景 if (!string.IsNullOrEmpty(_currentRoomScene) && _currentHandle.IsValid()) { var unloadOp = Addressables.UnloadSceneAsync(_currentHandle); yield return unloadOp; } _currentHandle = loadOp; _currentRoomScene = request.SceneName; _onSceneLoaded?.Raise(request.SceneName); } /// 手动卸载当前房间场景(供 SceneService 调用)。 public IEnumerator UnloadCurrentCoroutine() { if (!_currentHandle.IsValid()) yield break; var unloadOp = Addressables.UnloadSceneAsync(_currentHandle); yield return unloadOp; _currentRoomScene = null; } } }