164 lines
5.4 KiB
C#
164 lines
5.4 KiB
C#
using Cysharp.Threading.Tasks;
|
|
using PhxhSDK;
|
|
using PhxhSDK.Res;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace Gameplay.SubSystems
|
|
{
|
|
/// <summary>
|
|
/// 游戏场景的底层逻辑
|
|
/// </summary>
|
|
public class GameSceneManager : Singlenton<GameSceneManager>
|
|
{
|
|
/// <summary>
|
|
/// 空场景名
|
|
/// </summary>
|
|
private const string EMPTY_SCENE = "Empty.unity";
|
|
/// <summary>
|
|
/// 空场景路径
|
|
/// </summary>
|
|
private readonly string EMPTY_SCENE_PATH = $"Assets/Scenes/{EMPTY_SCENE}";
|
|
/// <summary>
|
|
/// 是否使用低品质场景
|
|
/// </summary>
|
|
private bool useLowScene;
|
|
/// <summary>
|
|
/// 场景加载器
|
|
/// </summary>
|
|
private readonly ISceneLoader sceneLoader;
|
|
/// <summary>
|
|
/// 加载中的场景列表
|
|
/// </summary>
|
|
private readonly HashSet<string> setLoadingScene = new();
|
|
/// <summary>
|
|
/// 等待卸载的场景
|
|
/// </summary>
|
|
private string waitUnloadScene;
|
|
|
|
public GameSceneManager()
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (!Application.isPlaying)
|
|
{
|
|
sceneLoader = new SceneLoader_Fake();
|
|
return;
|
|
}
|
|
#endif
|
|
#if USE_YOO
|
|
sceneLoader = new SceneLoader_YooAsset();
|
|
#else
|
|
_sceneLoader = new SceneLoader_Addressables();
|
|
#endif
|
|
}
|
|
|
|
public void SetSceneLoadingSetting(bool isUseLowScene)
|
|
{
|
|
useLowScene = isUseLowScene;
|
|
}
|
|
|
|
public async UniTask<SceneHandle> LoadSceneAsync(string scenePath, LoadSceneMode mode = LoadSceneMode.Single)
|
|
{
|
|
string realScenePath = await GetPostProcessedScenePath(scenePath); // 真实加载路径
|
|
|
|
if (string.IsNullOrEmpty(realScenePath))
|
|
{
|
|
DebugUtil.LogError($"转换后的场景路径为空!无法加载");
|
|
return null;
|
|
}
|
|
|
|
if (!setLoadingScene.Add(realScenePath))
|
|
{
|
|
DebugUtil.LogError($"上一个相同场景还在加载中,请等待加载完成后再次加载:{realScenePath}");
|
|
return null;
|
|
}
|
|
|
|
PhxhSDK.Res.SceneHandle sceneHandle = null;
|
|
if (!sceneLoader.IsExistScene(realScenePath))
|
|
{
|
|
if (LoadSceneMode.Single == mode)
|
|
{
|
|
// 先切换到Empty场景
|
|
await sceneLoader.LoadSceneAsync(EMPTY_SCENE_PATH, true);
|
|
await Resources.UnloadUnusedAssets();
|
|
}
|
|
|
|
sceneHandle = await sceneLoader.LoadSceneAsync(realScenePath, false, mode);
|
|
}
|
|
|
|
setLoadingScene.Remove(realScenePath);
|
|
|
|
if (!string.IsNullOrEmpty(waitUnloadScene))
|
|
{
|
|
if (scenePath == waitUnloadScene)
|
|
{
|
|
DebugUtil.Log($"等待卸载的场景和当前加载的场景一样,不卸载:{waitUnloadScene}");
|
|
|
|
waitUnloadScene = null;
|
|
}
|
|
else
|
|
{
|
|
DebugUtil.Log($"卸载之前的场景:{waitUnloadScene}");
|
|
|
|
await UnLoadSceneAsync(waitUnloadScene);
|
|
waitUnloadScene = null;
|
|
}
|
|
}
|
|
|
|
if (mode == LoadSceneMode.Single)
|
|
await sceneLoader.UnAllLoadSceneAsync(realScenePath);
|
|
|
|
return sceneHandle;
|
|
}
|
|
|
|
public async UniTask UnLoadSceneAsync(string scenePath)
|
|
{
|
|
string realScenePath = await GetPostProcessedScenePath(scenePath);
|
|
|
|
if (string.IsNullOrEmpty(realScenePath))
|
|
{
|
|
DebugUtil.LogError($"卸载失败,路径:{realScenePath}");
|
|
return;
|
|
}
|
|
|
|
await sceneLoader.UnLoadSceneAsync(realScenePath);
|
|
if (null != scenePath && string.Empty != scenePath)
|
|
waitUnloadScene = scenePath;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回场景加载的进度
|
|
/// </summary>
|
|
/// <param name="scenePath"></param>
|
|
/// <returns>0-100的浮点数</returns>
|
|
public async UniTask<float> GetSceneLoadingProgress(string scenePath)
|
|
{
|
|
var path = await GetPostProcessedScenePath(scenePath);
|
|
return sceneLoader.GetSceneLoadingProgress(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取后处理场景路径
|
|
/// </summary>
|
|
/// <param name="scenePath"></param>
|
|
/// <returns></returns>
|
|
private async UniTask<string> GetPostProcessedScenePath(string scenePath)
|
|
{
|
|
if (scenePath.Equals(EMPTY_SCENE))
|
|
return scenePath;
|
|
|
|
if (useLowScene && !scenePath.Contains("_low"))
|
|
{
|
|
string lowScenePath = scenePath.Replace(".unity", "_low.unity");
|
|
string realPath = await PostProcessData.GetPostProcessedPath(lowScenePath);
|
|
if (null == realPath || string.Empty == realPath)
|
|
return await PostProcessData.GetPostProcessedPath(scenePath);
|
|
else
|
|
return await PostProcessData.GetPostProcessedPath(lowScenePath);
|
|
}
|
|
|
|
return await PostProcessData.GetPostProcessedPath(scenePath);
|
|
}
|
|
}
|
|
} |