61 lines
2.4 KiB
C#
61 lines
2.4 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// Addressables 场景加载器(纯工具组件,由 SceneService 驱动)。
|
||
/// 采用"先加载新、再卸载旧"策略,保证加载失败时旧场景仍可用。
|
||
/// 加载完成后发布 EVT_SceneLoaded 事件。
|
||
/// 不直接订阅 SceneLoadRequestEventChannelSO;事件分发由 SceneService 负责。
|
||
/// </summary>
|
||
[DefaultExecutionOrder(-950)]
|
||
public class SceneLoader : MonoBehaviour
|
||
{
|
||
[Header("Event Channels - Raise")]
|
||
[SerializeField] private StringEventChannelSO _onSceneLoaded;
|
||
|
||
private string _currentRoomScene;
|
||
private AsyncOperationHandle<SceneInstance> _currentHandle;
|
||
|
||
public 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);
|
||
}
|
||
|
||
/// <summary>手动卸载当前房间场景(供 SceneService 调用)。</summary>
|
||
public IEnumerator UnloadCurrentCoroutine()
|
||
{
|
||
if (!_currentHandle.IsValid()) yield break;
|
||
var unloadOp = Addressables.UnloadSceneAsync(_currentHandle);
|
||
yield return unloadOp;
|
||
_currentRoomScene = null;
|
||
}
|
||
}
|
||
}
|