NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/SubSystems/GameSceneManager.cs

110 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using PhxhSDK;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
namespace Gameplay.SubSystems
{
/// <summary>
/// 游戏场景的底层逻辑
/// </summary>
public class GameSceneManager : Singlenton<GameSceneManager>
{
public class SceneHandle
{
public Scene Scene { get; private set; }
public SceneHandle(Scene scene)
{
Scene = scene;
}
public Camera SceneMainCamera => CommonUtils.GetSceneRootComponent<Camera>(Scene);
}
private Dictionary<string, AsyncOperationHandle<SceneInstance>> _sceneOpDic = new();
private string _lastSceneToBeUnload;
private string GetPostProcessedScenePath(string scenePath) => PostProcessData.Instance[scenePath];
public async UniTask<SceneHandle> LoadSceneAsync(string scenePath, LoadSceneMode mode = LoadSceneMode.Single)
{
scenePath = GetPostProcessedScenePath(scenePath);
if (string.IsNullOrEmpty(scenePath))
{
DebugUtil.LogError($"ScenePath is null!");
return null;
}
if (mode == LoadSceneMode.Single)
{
_sceneOpDic.Clear();
_lastSceneToBeUnload = null;
}
if (!_sceneOpDic.TryGetValue(scenePath, out var op))
{
op = Addressables.LoadSceneAsync(scenePath, mode);
_sceneOpDic.Add(scenePath, op);
}
await op;
if (!string.IsNullOrEmpty(_lastSceneToBeUnload))
{
UnLoadSceneAsync(_lastSceneToBeUnload);
_lastSceneToBeUnload = null;
}
return new(op.Result.Scene);
}
public async UniTask UnLoadSceneAsync(string scenePath)
{
scenePath = GetPostProcessedScenePath(scenePath);
if (string.IsNullOrEmpty(scenePath))
{
DebugUtil.LogError($"ScenePath is null!");
return;
}
if (!_sceneOpDic.TryGetValue(scenePath, out var op))
{
DebugUtil.LogError($"该场景没有被加载过 scenePath:{scenePath}");
return;
}
if (_sceneOpDic.Count == 1)
{
//如果只剩下一个场景了那么此次unload必然失败要等到下一次load新场景后重新unload
_lastSceneToBeUnload = scenePath;
}
else
{
_sceneOpDic.Remove(scenePath);
await Addressables.UnloadSceneAsync(op);
}
}
/// <summary>
/// 返回场景加载的进度
/// </summary>
/// <param name="scenePath"></param>
/// <returns>0-100的浮点数</returns>
public float GetSceneLoadingProgress(string scenePath)
{
scenePath = GetPostProcessedScenePath(scenePath);
if (_sceneOpDic.TryGetValue(scenePath, out var op))
{
return op.PercentComplete * 100;
}
return 0;
}
}
}