chore: initial commit
This commit is contained in:
92
Assets/Scripts/Core/SceneService.cs
Normal file
92
Assets/Scripts/Core/SceneService.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user