using Cysharp.Threading.Tasks;
using PhxhSDK;
using PhxhSDK.Res;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Gameplay.SubSystems
{
///
/// 游戏场景的底层逻辑
///
public class GameSceneManager : Singlenton
{
///
/// 空场景名
///
private const string EMPTY_SCENE = "Empty.unity";
///
/// 空场景路径
///
private readonly string EMPTY_SCENE_PATH = $"Assets/Scenes/{EMPTY_SCENE}";
///
/// 是否使用低品质场景
///
private bool useLowScene;
///
/// 场景加载器
///
private readonly ISceneLoader sceneLoader;
///
/// 加载中的场景列表
///
private readonly HashSet setLoadingScene = new();
///
/// 等待卸载的场景
///
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 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;*/
}
///
/// 返回场景加载的进度
///
///
/// 0-100的浮点数
public async UniTask GetSceneLoadingProgress(string scenePath)
{
var path = await GetPostProcessedScenePath(scenePath);
return sceneLoader.GetSceneLoadingProgress(path);
}
///
/// 获取后处理场景路径
///
///
///
private async UniTask 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);
}
}
}