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