131 lines
4.1 KiB
C#
131 lines
4.1 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using Cysharp.Threading.Tasks;
|
||
using Gameplay;
|
||
using Gameplay.SubSystems;
|
||
using PhxhSDK;
|
||
using UnityEngine;
|
||
using UnityEngine.SceneManagement;
|
||
|
||
/// <summary>
|
||
/// 游戏场景的通用业务逻辑
|
||
/// </summary>
|
||
public class GameSceneHelper : Singlenton<GameSceneHelper>
|
||
{
|
||
public enum EnumScene
|
||
{
|
||
GameStart, // 登录场景
|
||
GameMain, // 主场景
|
||
GameLevel // 关卡(战场)场景
|
||
}
|
||
|
||
public const string SCENE_PREFIX = "Assets/Scenes/";
|
||
public const string START_SCENE_NAME = "StartScene";
|
||
public const string LEVEL_SCENE_NAME = "LevelScene";
|
||
public const string MAIN_SCENE_NAME = "MainScene";
|
||
public const string SCENE_SUFFIX = ".unity";
|
||
|
||
private Dictionary<string, bool> _uiViewSceneDic = new();
|
||
|
||
public async UniTask<LoadingResult> ChangeScene(EnumScene enumScene)
|
||
{
|
||
string sceneName = SCENE_PREFIX;
|
||
switch (enumScene)
|
||
{
|
||
case EnumScene.GameStart:
|
||
sceneName += START_SCENE_NAME;
|
||
break;
|
||
case EnumScene.GameMain:
|
||
sceneName += MAIN_SCENE_NAME;
|
||
break;
|
||
case EnumScene.GameLevel:
|
||
sceneName += LEVEL_SCENE_NAME;
|
||
break;
|
||
default:
|
||
DebugUtil.LogError("{0}.ChangeScene, {1} has no scene name matched", GetType(), enumScene);
|
||
sceneName += START_SCENE_NAME;
|
||
break;
|
||
}
|
||
|
||
sceneName += SCENE_SUFFIX;
|
||
await GameSceneManager.Instance.LoadSceneAsync(sceneName);
|
||
|
||
return LoadingResult.Success;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打开UI预览场景,当某个UI需要单独渲染场景时使用(如PVP布阵,营地等)
|
||
/// 此时场景中的相机会只渲染UI场景内的物件
|
||
/// </summary>
|
||
/// <param name="scenePath"></param>
|
||
/// <param name="mode"></param>
|
||
/// <param name="switchMainCamera">打开场景后是否自动切换主相机</param>
|
||
/// <returns></returns>
|
||
public async UniTask<GameSceneManager.SceneHandle> LoadSceneForUIView(string scenePath,
|
||
LoadSceneMode mode = LoadSceneMode.Single, bool switchMainCamera = true)
|
||
{
|
||
var sceneHandle = await GameSceneManager.Instance.LoadSceneAsync(scenePath, mode);
|
||
if (sceneHandle == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
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层
|
||
root.SetLayerEx(UIViewLayer, groundLayer);
|
||
}
|
||
|
||
//设置相机的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);
|
||
if (switchMainCamera)
|
||
{
|
||
var sceneMainCamera = sceneHandle.SceneMainCamera;
|
||
CameraManager.Instance.SwitchMainCamera(sceneMainCamera);
|
||
}
|
||
|
||
_uiViewSceneDic.Add(scenePath, switchMainCamera);
|
||
return sceneHandle;
|
||
}
|
||
|
||
public async UniTask UnLoadSceneForUIView(string scenePath)
|
||
{
|
||
if (!_uiViewSceneDic.TryGetValue(scenePath, out var switchMainCamera))
|
||
{
|
||
DebugUtil.LogError($"没有加载过场景!scenePath:{scenePath}");
|
||
return;
|
||
}
|
||
|
||
await GameSceneManager.Instance.UnLoadSceneAsync(scenePath);
|
||
if (switchMainCamera)
|
||
{
|
||
CameraManager.Instance.RevertMainCamera();
|
||
}
|
||
|
||
_uiViewSceneDic.Remove(scenePath);
|
||
}
|
||
} |