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
|
|
|
|
|
|
{
|
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-08-22 19:08:45 +08:00
|
|
|
|
public enum EnumScene
|
|
|
|
|
|
{
|
|
|
|
|
|
GameStart, // 登录场景
|
|
|
|
|
|
GameMain, // 主场景
|
|
|
|
|
|
GameLevel // 关卡(战场)场景
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
public const string SCENE_PREFIX = "Assets/Scenes/";
|
2023-08-22 19:08:45 +08:00
|
|
|
|
public const string START_SCENE_NAME = "StartScene";
|
|
|
|
|
|
public const string LEVEL_SCENE_NAME = "LevelScene";
|
|
|
|
|
|
public const string MAIN_SCENE_NAME = "MainScene";
|
2023-10-19 15:00:19 +08:00
|
|
|
|
public const string SCENE_SUFFIX = ".unity";
|
2023-08-22 19:08:45 +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-05 14:24:46 +08:00
|
|
|
|
public async UniTask<LoadingResult> ChangeScene(EnumScene enumScene)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
|
string sceneName = SCENE_PREFIX;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
switch (enumScene)
|
|
|
|
|
|
{
|
|
|
|
|
|
case EnumScene.GameStart:
|
2023-10-19 15:00:19 +08:00
|
|
|
|
sceneName += START_SCENE_NAME;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case EnumScene.GameMain:
|
2023-10-19 15:00:19 +08:00
|
|
|
|
sceneName += MAIN_SCENE_NAME;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case EnumScene.GameLevel:
|
2023-10-19 15:00:19 +08:00
|
|
|
|
sceneName += LEVEL_SCENE_NAME;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2023-11-21 15:04:56 +08:00
|
|
|
|
DebugUtil.LogError("{0}.ChangeScene, {1} has no scene name matched", GetType(), enumScene);
|
2023-10-19 15:00:19 +08:00
|
|
|
|
sceneName += START_SCENE_NAME;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2023-11-21 15:04:56 +08:00
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
sceneName += SCENE_SUFFIX;
|
2023-11-22 15:05:43 +08:00
|
|
|
|
await LoadSceneAsync(sceneName);
|
2024-01-05 14:24:46 +08:00
|
|
|
|
|
|
|
|
|
|
return LoadingResult.Success;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
|
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
|
|
|
|
{
|
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)
|
2023-11-22 15:05:43 +08:00
|
|
|
|
_sceneOpDic.Clear();
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await op.ToUniTask();
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(scenePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError($"ScenePath is null!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!_sceneOpDic.TryGetValue(scenePath, out var op))
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"该场景没有被加载过 scenePath:{scenePath}");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_sceneOpDic.Remove(scenePath);
|
|
|
|
|
|
await Addressables.UnloadSceneAsync(op).ToUniTask();
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
2023-12-29 15:07:04 +08:00
|
|
|
|
|
|
|
|
|
|
public float GetSceneLoadingProgress(string scenePath)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_sceneOpDic.TryGetValue(scenePath, out var op))
|
|
|
|
|
|
{
|
|
|
|
|
|
return op.PercentComplete;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
2024-01-02 14:16:25 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 打开UI预览场景,当某个UI需要单独渲染场景时使用(如PVP布阵,营地等)
|
|
|
|
|
|
/// 此时场景中的相机会只渲染UI场景内的物件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="scenePath"></param>
|
|
|
|
|
|
/// <param name="mode"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2024-01-08 13:59:23 +08:00
|
|
|
|
public async UniTask<SceneHandle> LoadSceneForUIView(string scenePath,
|
2023-12-29 19:58:17 +08:00
|
|
|
|
LoadSceneMode mode = LoadSceneMode.Single)
|
|
|
|
|
|
{
|
|
|
|
|
|
var sceneHandle = await LoadSceneAsync(scenePath, mode);
|
|
|
|
|
|
if (sceneHandle == null)
|
|
|
|
|
|
{
|
2024-01-08 13:59:23 +08:00
|
|
|
|
return null;
|
2023-12-29 19:58:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var scene = sceneHandle.Scene;
|
|
|
|
|
|
var groundLayer = LayerMask.NameToLayer("Ground");
|
|
|
|
|
|
var UIViewLayer = LayerMask.NameToLayer("UIView");
|
|
|
|
|
|
var UIViewMask = LayerMask.GetMask("UIView","Ground");
|
|
|
|
|
|
//调整所有物品的层级
|
|
|
|
|
|
var roots = scene.GetRootGameObjects();
|
|
|
|
|
|
foreach (var root in roots)
|
|
|
|
|
|
{
|
|
|
|
|
|
//将所有gameObject设置为UIView层
|
2024-01-02 12:59:01 +08:00
|
|
|
|
root.SetLayerEx(UIViewLayer,groundLayer);
|
2023-12-29 19:58:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//设置相机的culling mask
|
|
|
|
|
|
foreach (var root in roots)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cam = root.GetComponent<Camera>();
|
|
|
|
|
|
if (!cam)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
cam.cullingMask = UIViewMask;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//设置光源culling mask
|
|
|
|
|
|
var lights = Object.FindObjectsOfType<Light>();
|
|
|
|
|
|
foreach (var light in lights)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (light.gameObject.scene != scene)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
light.cullingMask = UIViewMask;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//切换全局GI
|
|
|
|
|
|
SceneManager.SetActiveScene(scene);
|
2024-01-08 13:59:23 +08:00
|
|
|
|
var result = new SceneHandle(scene);
|
2024-01-10 18:51:57 +08:00
|
|
|
|
//CameraManager.Instance.AddCameraStack(sceneHandle.SceneMainCamera);
|
|
|
|
|
|
sceneHandle.SceneMainCamera.targetTexture = CameraManager.Instance.MainCamera.targetTexture;
|
2024-01-08 13:59:23 +08:00
|
|
|
|
return result;
|
2023-12-29 19:58:17 +08:00
|
|
|
|
}
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|