using System.Collections; using UnityEngine; using BaseGames.Core.Assets; using BaseGames.Core.Events; namespace BaseGames.Core { /// /// 场景管理服务接口。 /// public interface ISceneService { /// 异步加载指定场景(Additive)。 IEnumerator LoadSceneCoroutine(SceneLoadRequest request); /// 卸载当前房间场景(保留 Persistent)。 IEnumerator UnloadCurrentRoomCoroutine(); /// 加载主菜单。 IEnumerator LoadMainMenuCoroutine(); } /// /// 场景管理服务。 /// [DefaultExecutionOrder(-900)] public class SceneService : MonoBehaviour, ISceneService { [Header("Event Channels - Listen")] [SerializeField] private SceneLoadRequestEventChannelSO _onSceneLoadRequest; [Header("Event Channels - Raise")] [SerializeField] private VoidEventChannelSO _onFadeInRequest; [SerializeField] private VoidEventChannelSO _onFadeOutRequest; [SerializeField] private SceneLoader _sceneLoader; [SerializeField] private float _fadeDuration = 0.3f; private readonly CompositeDisposable _subscriptions = new(); private void OnEnable() { _onSceneLoadRequest?.Subscribe(HandleSceneLoadRequest).AddTo(_subscriptions); } private void OnDisable() => _subscriptions.Clear(); private void HandleSceneLoadRequest(SceneLoadRequest request) => StartCoroutine(LoadSceneCoroutine(request)); public IEnumerator LoadSceneCoroutine(SceneLoadRequest request) { _onFadeOutRequest?.Raise(); yield return new WaitForSeconds(_fadeDuration); if (_sceneLoader != null) yield return StartCoroutine(_sceneLoader.LoadSceneCoroutine(request)); else Debug.LogError("[SceneService] _sceneLoader 未赋值,场景加载中断。请在 Inspector 中绑定 SceneLoader 组件。"); _onFadeInRequest?.Raise(); } public IEnumerator UnloadCurrentRoomCoroutine() { if (_sceneLoader != null) yield return StartCoroutine(_sceneLoader.UnloadCurrentCoroutine()); } public IEnumerator LoadMainMenuCoroutine() { yield return LoadSceneCoroutine(new SceneLoadRequest { SceneName = AddressKeys.SceneMainMenu, EntryTransitionId = null, ShowLoadingScreen = false, IsRespawn = false }); } } }