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

163 lines
5.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using PhxhSDK;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
namespace Gameplay.SubSystems
{
public class GameSceneManager : Singlenton<GameSceneManager>
{
public class SceneHandle
{
public Scene Scene { get; private set; }
public SceneHandle(Scene scene)
{
Scene = scene;
}
}
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, AsyncOperationHandle<SceneInstance>> _sceneOpDic = new();
public async UniTask 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 LoadSceneAsync(sceneName);
}
public async UniTask<SceneHandle> LoadSceneAsync(string scenePath, LoadSceneMode mode = LoadSceneMode.Single)
{
if (string.IsNullOrEmpty(scenePath))
{
DebugUtil.LogError($"ScenePath is null!");
return null;
}
if (mode == LoadSceneMode.Single)
_sceneOpDic.Clear();
if (!_sceneOpDic.TryGetValue(scenePath, out var op))
{
op = Addressables.LoadSceneAsync(scenePath, mode);
_sceneOpDic.Add(scenePath, op);
}
await op.ToUniTask();
return new(op.Result.Scene);
}
public async UniTask UnLoadSceneAsync(string scenePath)
{
if (string.IsNullOrEmpty(scenePath))
{
DebugUtil.LogError($"ScenePath is null!");
return;
}
if (!_sceneOpDic.TryGetValue(scenePath, out var op))
{
Debug.LogError($"该场景没有被加载过 scenePath:{scenePath}");
return;
}
_sceneOpDic.Remove(scenePath);
await Addressables.UnloadSceneAsync(op).ToUniTask();
}
public float GetSceneLoadingProgress(string scenePath)
{
if (_sceneOpDic.TryGetValue(scenePath, out var op))
{
return op.PercentComplete;
}
return 0;
}
/// <summary>
/// 打开UI预览场景当某个UI需要单独渲染场景时使用(如PVP布阵营地等)
/// 此时场景中的相机会只渲染UI场景内的物件
/// </summary>
/// <param name="scenePath"></param>
/// <param name="mode"></param>
/// <returns></returns>
public async UniTask LoadSceneForUIView(string scenePath,
LoadSceneMode mode = LoadSceneMode.Single)
{
var sceneHandle = await LoadSceneAsync(scenePath, mode);
if (sceneHandle == null)
{
return;
}
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);
}
}
}