Files
zeling_v2/Assets/Scripts/Core/SceneService.cs
2026-05-08 11:04:00 +08:00

93 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using BaseGames.Core.Events;
namespace BaseGames.Core
{
/// <summary>
/// 场景管理服务接口。
/// </summary>
public interface ISceneService
{
/// <summary>异步加载指定场景Additive。</summary>
IEnumerator LoadSceneCoroutine(SceneLoadRequest request);
/// <summary>卸载当前房间场景(保留 Persistent。</summary>
IEnumerator UnloadCurrentRoomCoroutine();
/// <summary>加载主菜单。</summary>
IEnumerator LoadMainMenuCoroutine();
}
/// <summary>
/// 场景管理服务Phase 0 骨架Phase 1 完整实现)。
/// </summary>
[DefaultExecutionOrder(-900)]
public class SceneService : MonoBehaviour, ISceneService
{
[Header("Event Channels - Listen")]
[SerializeField] private SceneLoadRequestEventChannelSO _onSceneLoadRequest;
[Header("Event Channels - Raise")]
[SerializeField] private StringEventChannelSO _onSceneLoaded;
[SerializeField] private VoidEventChannelSO _onFadeInRequest;
[SerializeField] private VoidEventChannelSO _onFadeOutRequest;
[SerializeField] private float _fadeDuration = 0.3f;
private string _currentRoomScene;
private void OnEnable()
{
if (_onSceneLoadRequest != null)
_onSceneLoadRequest.OnEventRaised += HandleSceneLoadRequest;
}
private void OnDisable()
{
if (_onSceneLoadRequest != null)
_onSceneLoadRequest.OnEventRaised -= HandleSceneLoadRequest;
}
private void HandleSceneLoadRequest(SceneLoadRequest request)
=> StartCoroutine(LoadSceneCoroutine(request));
public IEnumerator LoadSceneCoroutine(SceneLoadRequest request)
{
_onFadeOutRequest?.Raise();
yield return new WaitForSeconds(_fadeDuration);
if (!string.IsNullOrEmpty(_currentRoomScene))
{
var unload = SceneManager.UnloadSceneAsync(_currentRoomScene);
yield return new WaitUntil(() => unload.isDone);
}
var load = SceneManager.LoadSceneAsync(request.SceneName, LoadSceneMode.Additive);
yield return new WaitUntil(() => load.isDone);
_currentRoomScene = request.SceneName;
_onSceneLoaded?.Raise(request.SceneName);
_onFadeInRequest?.Raise();
}
public IEnumerator UnloadCurrentRoomCoroutine()
{
if (string.IsNullOrEmpty(_currentRoomScene)) yield break;
var op = SceneManager.UnloadSceneAsync(_currentRoomScene);
yield return new WaitUntil(() => op.isDone);
_currentRoomScene = null;
}
public IEnumerator LoadMainMenuCoroutine()
{
yield return LoadSceneCoroutine(new SceneLoadRequest
{
SceneName = "MainMenu",
EntryTransitionId = null,
ShowLoadingScreen = false,
IsRespawn = false
});
}
}
}