2024-01-15 15:38:20 +08:00
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using Cysharp.Threading.Tasks;
|
2024-04-03 14:23:41 +08:00
|
|
|
|
using Framework;
|
2024-01-15 15:38:20 +08:00
|
|
|
|
using Gameplay;
|
2024-04-30 14:30:12 +08:00
|
|
|
|
using Gameplay.Performance;
|
2024-01-15 15:38:20 +08:00
|
|
|
|
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;
|
2024-04-03 14:23:41 +08:00
|
|
|
|
using Constants = Framework.Constants;
|
2024-01-15 15:38:20 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 游戏场景的通用业务逻辑
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class GameSceneHelper : Singlenton<GameSceneHelper>
|
|
|
|
|
|
{
|
2024-02-21 17:54:08 +08:00
|
|
|
|
private Stack<(string, SceneHandle)> _uiViewSceneStack = new();
|
2024-03-29 12:05:14 +08:00
|
|
|
|
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场景内的物件
|
|
|
|
|
|
/// 并处理了光照,全局GI,Volume,单一主相机
|
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-06-06 15:39:43 +08:00
|
|
|
|
|
|
|
|
|
|
// DebugUtil.Log($"加载UIView场景:{scenePath}");
|
2024-04-03 14:23:41 +08:00
|
|
|
|
SceneHandle 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-17 16:49:32 +08:00
|
|
|
|
{
|
2024-01-19 17:03:07 +08:00
|
|
|
|
if (_uiViewSceneStack.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
//如果之前加载过UIView场景,则使得上一个场景不影响当前场景
|
2024-04-03 14:23:41 +08:00
|
|
|
|
(string, SceneHandle) lastUIViewSceneData = _uiViewSceneStack.Peek();
|
2024-01-19 17:03:07 +08:00
|
|
|
|
SetSceneActiveForUIView(lastUIViewSceneData.Item2, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
_uiViewSceneStack.Clear();
|
2024-01-17 16:49:32 +08:00
|
|
|
|
|
|
|
|
|
|
SetSceneActiveForUIView(sceneHandle, true);
|
|
|
|
|
|
|
|
|
|
|
|
_uiViewSceneStack.Push((scenePath, sceneHandle));
|
2024-04-03 14:23:41 +08:00
|
|
|
|
|
2024-01-17 16:49:32 +08:00
|
|
|
|
return sceneHandle;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-03 14:23:41 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 卸载场景
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
2024-01-17 16:49:32 +08:00
|
|
|
|
public async UniTask UnloadSceneForUIView()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_uiViewSceneStack.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError($"没有加载过UIView场景");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-03 14:23:41 +08:00
|
|
|
|
(string, SceneHandle) sceneData = _uiViewSceneStack.Pop();
|
2024-01-17 16:49:32 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2024-04-03 14:23:41 +08:00
|
|
|
|
(string, SceneHandle) lastUIViewSceneData = _uiViewSceneStack.Peek();
|
2024-01-17 17:17:39 +08:00
|
|
|
|
SetSceneActiveForUIView(lastUIViewSceneData.Item2, true);
|
|
|
|
|
|
}
|
2024-01-17 16:49:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-03 14:23:41 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置激活场景
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sceneHandle"></param>
|
|
|
|
|
|
/// <param name="isActive"></param>
|
2024-05-14 17:03:52 +08:00
|
|
|
|
public void SetSceneActiveForUIView(SceneHandle sceneHandle, bool isActive)
|
2024-01-17 16:49:32 +08:00
|
|
|
|
{
|
2024-04-03 14:23:41 +08:00
|
|
|
|
Scene scene = sceneHandle.Scene;
|
2024-03-04 19:32:32 +08:00
|
|
|
|
if (!scene.IsValid())
|
|
|
|
|
|
return;
|
2024-04-03 14:23:41 +08:00
|
|
|
|
|
|
|
|
|
|
int groundLayer = Constants.Layer.GROUND;
|
|
|
|
|
|
int layerToSet = isActive ? Constants.Layer.UIVIEW : Constants.Layer.DEFAULT;
|
|
|
|
|
|
int maskToSet = isActive ? LayerMask.GetMask(Constants.Layer.UIVIEW_NAME, Constants.Layer.GROUND_NAME) :
|
|
|
|
|
|
LayerMask.GetMask(Constants.Layer.DEFAULT_NAME, Constants.Layer.GROUND_NAME);
|
2024-01-15 15:38:20 +08:00
|
|
|
|
//调整所有物品的层级
|
2024-03-04 19:32:32 +08:00
|
|
|
|
|
2024-04-03 14:23:41 +08:00
|
|
|
|
GameObject[] roots = scene.GetRootGameObjects();
|
|
|
|
|
|
foreach (GameObject root in roots)
|
2024-01-15 15:38:20 +08:00
|
|
|
|
{
|
|
|
|
|
|
//将所有gameObject设置为UIView层
|
2024-01-17 18:59:23 +08:00
|
|
|
|
root.SetLayerEx(layerToSet, groundLayer);
|
2024-04-03 17:15:50 +08:00
|
|
|
|
root.SetActive(isActive);
|
2024-01-15 15:38:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-08 13:47:25 +08:00
|
|
|
|
Volume volume = sceneHandle.GetSceneVolume();
|
|
|
|
|
|
if (volume != null)
|
|
|
|
|
|
volume.enabled = isActive;
|
|
|
|
|
|
|
2024-04-03 14:23:41 +08:00
|
|
|
|
Camera sceneMainCamera = sceneHandle.SceneMainCamera;
|
2024-01-17 16:49:32 +08:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-17 16:49:32 +08:00
|
|
|
|
if (isActive)
|
2024-01-15 15:38:20 +08:00
|
|
|
|
{
|
2024-01-17 16:49:32 +08:00
|
|
|
|
//切换全局GI
|
|
|
|
|
|
SceneManager.SetActiveScene(scene);
|
|
|
|
|
|
//切换主相机
|
2024-01-15 15:38:20 +08:00
|
|
|
|
CameraManager.Instance.SwitchMainCamera(sceneMainCamera);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-01-17 20:00:46 +08:00
|
|
|
|
|
2024-03-29 12:05:14 +08:00
|
|
|
|
public RenderTexture GetRenderTexture()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!_rTexture)
|
|
|
|
|
|
{
|
|
|
|
|
|
_CreateRt();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return _rTexture;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void _CreateRt()
|
|
|
|
|
|
{
|
2024-08-15 16:53:50 +08:00
|
|
|
|
var rtFormat = PerformanceManager.instance.data.enableHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGB32;
|
2024-04-30 14:30:12 +08:00
|
|
|
|
_rTexture = RenderTexturePool.Instance.Create("GameSceneHelper_rt", PerformanceManager.instance.fullScreenWidth,
|
2024-08-15 16:53:50 +08:00
|
|
|
|
PerformanceManager.instance.fullScreenHeight, RenderTexturePool.DEFAULT_DEPTH, rtFormat);
|
2024-03-29 12:05:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void _ReleaseRt()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_rTexture)
|
|
|
|
|
|
{
|
|
|
|
|
|
RenderTexturePool.Instance.Destroy(_rTexture);
|
|
|
|
|
|
_rTexture = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-03 14:23:41 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取当前显示的场景
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
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;
|
|
|
|
|
|
}
|
2024-03-14 16:41:05 +08:00
|
|
|
|
|
2024-04-03 14:23:41 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 切换当前显示的场景
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="scenePath"></param>
|
|
|
|
|
|
/// <param name="loadSceneMode"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public void ChangeSceneForUIView(string scenePath)
|
2024-03-14 16:41:05 +08:00
|
|
|
|
{
|
2024-04-03 14:44:01 +08:00
|
|
|
|
if (_uiViewSceneStack.Count <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError("当前没有场景");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-03 14:23:41 +08:00
|
|
|
|
Stack<(string, SceneHandle)> stackTemp = new();
|
|
|
|
|
|
SceneHandle curSceneHandle = null; // 要激活的场景
|
|
|
|
|
|
|
2024-04-03 14:44:01 +08:00
|
|
|
|
#region 校验当前场景是否是要切换的场景
|
|
|
|
|
|
(string, SceneHandle) lastUIViewScene = _uiViewSceneStack.Pop(); // 当前激活场景
|
|
|
|
|
|
if (lastUIViewScene.Item1.Equals(scenePath))
|
2024-03-14 16:41:05 +08:00
|
|
|
|
{
|
2024-04-03 14:44:01 +08:00
|
|
|
|
DebugUtil.LogWarning($"已经激活该场景{scenePath}");
|
|
|
|
|
|
_uiViewSceneStack.Push(lastUIViewScene);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
2024-04-03 14:23:41 +08:00
|
|
|
|
|
2024-04-03 14:44:01 +08:00
|
|
|
|
#region 遍历剩下的所有场景,获取要切换的场景,其余场景临时存起来
|
|
|
|
|
|
while (_uiViewSceneStack.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
(string, SceneHandle) uiViewScene = _uiViewSceneStack.Pop();
|
|
|
|
|
|
if (uiViewScene.Item1.Equals(scenePath))
|
2024-04-03 14:23:41 +08:00
|
|
|
|
{
|
2024-04-03 14:44:01 +08:00
|
|
|
|
curSceneHandle = uiViewScene.Item2;
|
|
|
|
|
|
break;
|
2024-04-03 14:23:41 +08:00
|
|
|
|
}
|
2024-04-03 14:44:01 +08:00
|
|
|
|
else
|
|
|
|
|
|
stackTemp.Push(uiViewScene);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
2024-04-03 14:23:41 +08:00
|
|
|
|
|
2024-04-03 14:44:01 +08:00
|
|
|
|
#region 先把临时存的场景放回栈中
|
|
|
|
|
|
while (stackTemp.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
_uiViewSceneStack.Push(stackTemp.Pop());
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
2024-04-03 14:23:41 +08:00
|
|
|
|
|
2024-04-03 14:44:01 +08:00
|
|
|
|
_uiViewSceneStack.Push(lastUIViewScene); // 放入上次激活的场景
|
2024-04-03 14:23:41 +08:00
|
|
|
|
|
2024-04-03 14:44:01 +08:00
|
|
|
|
if (curSceneHandle != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_uiViewSceneStack.Push((scenePath, curSceneHandle));
|
2024-04-03 14:23:41 +08:00
|
|
|
|
|
2024-04-03 14:44:01 +08:00
|
|
|
|
SetSceneActiveForUIView(lastUIViewScene.Item2, false);
|
|
|
|
|
|
SetSceneActiveForUIView(curSceneHandle, true);
|
2024-03-14 16:41:05 +08:00
|
|
|
|
}
|
2024-04-03 14:44:01 +08:00
|
|
|
|
else
|
|
|
|
|
|
DebugUtil.LogError($"没有加载场景{scenePath}");
|
2024-03-14 16:41:05 +08:00
|
|
|
|
}
|
2024-03-29 12:05:14 +08:00
|
|
|
|
|
|
|
|
|
|
public async UniTask<SceneHandle> LoadSceneForRt(string scenePath)
|
|
|
|
|
|
{
|
2024-08-12 14:01:56 +08:00
|
|
|
|
//var targetRt = CameraManager.Instance.MainCamera.targetTexture;
|
|
|
|
|
|
SetSceneActiveByIndex(0, false);
|
2024-03-29 12:05:14 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-12 14:01:56 +08:00
|
|
|
|
public void SetSceneActiveByIndex(int index, bool isActive)
|
|
|
|
|
|
{
|
|
|
|
|
|
var scene = SceneManager.GetSceneAt(index);
|
|
|
|
|
|
GameObject[] roots = scene.GetRootGameObjects();
|
|
|
|
|
|
foreach (GameObject root in roots)
|
|
|
|
|
|
{
|
|
|
|
|
|
//将所有gameObject设置为UIView层
|
|
|
|
|
|
//root.SetLayerEx(layerToSet, groundLayer);
|
|
|
|
|
|
root.SetActive(isActive);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-03-29 12:05:14 +08:00
|
|
|
|
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
|
|
|
|
}
|