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
});
}
}
}