NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/SubSystems/GameSceneHelper.cs

199 lines
5.9 KiB
C#
Raw Normal View History

2024-01-15 15:38:20 +08:00
using System.Collections;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Gameplay;
using Gameplay.SubSystems;
using PhxhSDK;
2024-02-21 17:54:08 +08:00
using PhxhSDK.Res;
2024-01-15 15:38:20 +08:00
using UnityEngine;
2024-01-17 17:17:39 +08:00
using UnityEngine.Rendering;
2024-01-17 18:59:23 +08:00
using UnityEngine.Rendering.Universal;
2024-01-15 15:38:20 +08:00
using UnityEngine.SceneManagement;
/// <summary>
/// 游戏场景的通用业务逻辑
/// </summary>
public class GameSceneHelper : Singlenton<GameSceneHelper>
{
2024-02-21 17:54:08 +08:00
private Stack<(string, SceneHandle)> _uiViewSceneStack = new();
private RenderTexture _rTexture;
private Stack<(string, SceneHandle)> _rtSceneStack = new ();
2024-01-15 15:38:20 +08:00
/// <summary>
/// 打开UI预览场景当某个UI需要单独渲染场景时使用(如PVP布阵营地等)
2024-01-17 17:17:39 +08:00
/// 该函数会使得预览场景中的相机只渲染UI场景内的物件
/// 并处理了光照全局GIVolume单一主相机
2024-01-15 15:38:20 +08:00
/// </summary>
/// <param name="scenePath"></param>
/// <returns></returns>
2024-03-04 19:32:32 +08:00
public async UniTask<SceneHandle> LoadSceneForUIView(string scenePath,
LoadSceneMode loadSceneMode = LoadSceneMode.Additive)
2024-01-15 15:38:20 +08:00
{
2024-01-19 17:03:07 +08:00
var sceneHandle = await GameSceneManager.Instance.LoadSceneAsync(scenePath, loadSceneMode);
2024-01-15 15:38:20 +08:00
if (sceneHandle == null)
{
return null;
}
2024-01-19 17:03:07 +08:00
if (loadSceneMode == LoadSceneMode.Additive)
{
2024-01-19 17:03:07 +08:00
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();
2024-02-21 17:54:08 +08:00
await GameSceneManager.Instance.UnLoadSceneAsync(sceneData.Item1);
2024-01-17 17:17:39 +08:00
if (_uiViewSceneStack.Count > 0)
{
var lastUIViewSceneData = _uiViewSceneStack.Peek();
SetSceneActiveForUIView(lastUIViewSceneData.Item2, true);
}
}
2024-03-04 19:32:32 +08:00
private void SetSceneActiveForUIView(SceneHandle sceneHandle,
bool isActive)
{
2024-01-15 15:38:20 +08:00
var scene = sceneHandle.Scene;
2024-03-04 19:32:32 +08:00
if (!scene.IsValid())
{
return;
}
2024-01-15 15:38:20 +08:00
var groundLayer = LayerMask.NameToLayer("Ground");
2024-01-17 18:59:23 +08:00
var layerToSet = isActive ? LayerMask.NameToLayer("UIView") : LayerMask.NameToLayer("Default");
var maskToSet = isActive ? LayerMask.GetMask("UIView", "Ground") : LayerMask.GetMask("Default", "Ground");
2024-01-15 15:38:20 +08:00
//调整所有物品的层级
2024-03-04 19:32:32 +08:00
2024-01-15 15:38:20 +08:00
var roots = scene.GetRootGameObjects();
foreach (var root in roots)
{
//将所有gameObject设置为UIView层
2024-01-17 18:59:23 +08:00
root.SetLayerEx(layerToSet, groundLayer);
2024-01-15 15:38:20 +08:00
}
var sceneMainCamera = sceneHandle.SceneMainCamera;
if (sceneMainCamera != null)
2024-01-17 18:59:23 +08:00
{
var additionalData = sceneMainCamera.GetUniversalAdditionalCameraData();
sceneMainCamera.cullingMask = maskToSet;
//volume处理
2024-03-04 19:32:32 +08:00
additionalData.volumeLayerMask = maskToSet;
2024-01-17 18:59:23 +08:00
}
2024-01-15 15:38:20 +08:00
//设置光源culling mask
var lights = Object.FindObjectsOfType<Light>();
foreach (var light in lights)
{
if (light.gameObject.scene != scene)
continue;
2024-01-17 18:59:23 +08:00
light.cullingMask = maskToSet;
2024-01-17 17:17:39 +08:00
}
if (isActive)
2024-01-15 15:38:20 +08:00
{
2024-03-04 19:32:32 +08:00
//切换全局GI
SceneManager.SetActiveScene(scene);
//切换主相机
2024-01-15 15:38:20 +08:00
CameraManager.Instance.SwitchMainCamera(sceneMainCamera);
2024-03-04 19:32:32 +08:00
2024-01-15 15:38:20 +08:00
}
}
2024-01-17 20:00:46 +08:00
public RenderTexture GetRenderTexture()
{
if (!_rTexture)
{
_CreateRt();
}
return _rTexture;
}
private void _CreateRt()
{
_rTexture = RenderTexturePool.Instance.Create("GameSceneHelper", Screen.width,
Screen.height, RenderTexturePool.DEFAULT_DEPTH);
_rTexture.name = "GameSceneHelper_rt";
}
private void _ReleaseRt()
{
if (_rTexture)
{
RenderTexturePool.Instance.Destroy(_rTexture);
_rTexture = null;
}
}
2024-02-21 17:54:08 +08:00
public SceneHandle GetCurrentUIViewScene()
2024-01-17 20:00:46 +08:00
{
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));
}
}
public async UniTask<SceneHandle> LoadSceneForRt(string scenePath)
{
var sceneHandle = await GameSceneManager.Instance.LoadSceneAsync(scenePath, LoadSceneMode.Additive);
if (sceneHandle == null)
{
return null;
}
var sceneCamera = sceneHandle.SceneMainCamera;
var rTexture = GetRenderTexture();
sceneCamera.targetTexture = rTexture;
_rtSceneStack.Push((scenePath, sceneHandle));
return sceneHandle;
}
public async UniTask UnLoadSceneForRt()
{
if (_rtSceneStack.Count > 0)
{
var item = _rtSceneStack.Pop();
await GameSceneManager.Instance.UnLoadSceneAsync(item.Item1);
_ReleaseRt();
}
}
2024-03-04 19:32:32 +08:00
}