using System.Collections; using System.Collections.Generic; using Cysharp.Threading.Tasks; using Gameplay; using Gameplay.SubSystems; using PhxhSDK; using PhxhSDK.Res; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using UnityEngine.SceneManagement; /// /// 游戏场景的通用业务逻辑 /// public class GameSceneHelper : Singlenton { private Stack<(string, SceneHandle)> _uiViewSceneStack = new(); /// /// 打开UI预览场景,当某个UI需要单独渲染场景时使用(如PVP布阵,营地等) /// 该函数会使得预览场景中的相机只渲染UI场景内的物件 /// 并处理了光照,全局GI,Volume,单一主相机 /// /// /// public async UniTask LoadSceneForUIView(string scenePath, LoadSceneMode loadSceneMode = LoadSceneMode.Additive) { var sceneHandle = await GameSceneManager.Instance.LoadSceneAsync(scenePath, loadSceneMode); if (sceneHandle == null) { return null; } if (loadSceneMode == LoadSceneMode.Additive) { if (_uiViewSceneStack.Count > 0) { //如果之前加载过UIView场景,则使得上一个场景不影响当前场景 var lastUIViewSceneData = _uiViewSceneStack.Peek(); SetSceneActiveForUIView(lastUIViewSceneData.Item2, false); } } else { _uiViewSceneStack.Clear(); } SetSceneActiveForUIView(sceneHandle, true); _uiViewSceneStack.Push((scenePath, sceneHandle)); return sceneHandle; } public async UniTask UnloadSceneForUIView() { if (_uiViewSceneStack.Count == 0) { DebugUtil.LogError($"没有加载过UIView场景"); return; } var sceneData = _uiViewSceneStack.Pop(); CameraManager.Instance.RevertMainCamera(); await GameSceneManager.Instance.UnLoadSceneAsync(sceneData.Item1); if (_uiViewSceneStack.Count > 0) { var lastUIViewSceneData = _uiViewSceneStack.Peek(); SetSceneActiveForUIView(lastUIViewSceneData.Item2, true); } } private void SetSceneActiveForUIView(SceneHandle sceneHandle, bool isActive) { var scene = sceneHandle.Scene; if (!scene.IsValid()) { return; } var groundLayer = LayerMask.NameToLayer("Ground"); var layerToSet = isActive ? LayerMask.NameToLayer("UIView") : LayerMask.NameToLayer("Default"); var maskToSet = isActive ? LayerMask.GetMask("UIView", "Ground") : LayerMask.GetMask("Default", "Ground"); //调整所有物品的层级 var roots = scene.GetRootGameObjects(); foreach (var root in roots) { //将所有gameObject设置为UIView层 root.SetLayerEx(layerToSet, groundLayer); } var sceneMainCamera = sceneHandle.SceneMainCamera; if (sceneMainCamera != null) { var additionalData = sceneMainCamera.GetUniversalAdditionalCameraData(); sceneMainCamera.cullingMask = maskToSet; //volume处理 additionalData.volumeLayerMask = maskToSet; } //设置光源culling mask var lights = Object.FindObjectsOfType(); foreach (var light in lights) { if (light.gameObject.scene != scene) continue; light.cullingMask = maskToSet; } if (isActive) { //切换全局GI SceneManager.SetActiveScene(scene); //切换主相机 CameraManager.Instance.SwitchMainCamera(sceneMainCamera); } } public SceneHandle GetCurrentUIViewScene() { if (_uiViewSceneStack.Count == 0) return null; return _uiViewSceneStack.Peek().Item2; } public async UniTask ChangeSceneForUIView(string scenePath, LoadSceneMode loadSceneMode = LoadSceneMode.Single) { if (_uiViewSceneStack.Count > 0) { var uiViewScene = _uiViewSceneStack.Pop(); var sceneHandle = await GameSceneManager.Instance.LoadSceneAsync(scenePath, loadSceneMode); if (sceneHandle == null) { return; } _uiViewSceneStack.Push((scenePath, sceneHandle)); } } }