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