增加场景管理模块。

增加场景管理模块。
This commit is contained in:
ALEXTANG
2023-10-18 16:42:44 +08:00
parent d8f8514f9d
commit 0d09a7e73b
9 changed files with 429 additions and 1 deletions

View File

@@ -123,6 +123,50 @@ NavMeshSettings:
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &450845952
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 450845953}
- component: {fileID: 450845954}
m_Layer: 0
m_Name: Scene
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &450845953
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 450845952}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 709048975}
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &450845954
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 450845952}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 86342cc6845c403da1a3f6db507fae9d, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &553327090
GameObject:
m_ObjectHideFlags: 0
@@ -405,6 +449,7 @@ Transform:
- {fileID: 1666908677}
- {fileID: 1863338241}
- {fileID: 914171638}
- {fileID: 450845953}
- {fileID: 1047779124}
m_Father: {fileID: 1195690679}
m_RootOrder: 0
@@ -768,6 +813,7 @@ MonoBehaviour:
milliseconds: 30
downloadingMaxNum: 3
failedTryAgain: 3
adaptiveReplacementCacheCapacity: 32
--- !u!1 &1047779123
GameObject:
m_ObjectHideFlags: 0
@@ -798,7 +844,7 @@ Transform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 709048975}
m_RootOrder: 10
m_RootOrder: 11
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1047779125
MonoBehaviour:

View File

@@ -82,6 +82,12 @@ namespace TEngine
private static LocalizationModule _localization;
/// <summary>
/// 获取场景模块。
/// </summary>
public static SceneModule Scene => _scene ??= Get<SceneModule>();
private static SceneModule _scene;
#endregion
/// <summary>

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2c67061fae264c5a861a5bdb257128a2
timeCreated: 1697614501

View File

@@ -0,0 +1,61 @@
using System;
using UnityEngine.SceneManagement;
using YooAsset;
namespace TEngine
{
public interface ISceneModule
{
/// <summary>
/// 当前主场景名称。
/// </summary>
public string CurrentMainSceneName { get; }
/// <summary>
/// 加载场景。
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="suspendLoad">加载完毕时是否主动挂起</param>
/// <param name="priority">优先级</param>
/// <param name="callBack">加载回调。</param>
/// <param name="gcCollect">加载主场景是否回收垃圾。</param>
public void LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100,
Action<SceneOperationHandle> callBack = null, bool gcCollect = true);
/// <summary>
/// 激活场景(当同时存在多个场景时用于切换激活场景)。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否操作成功。</returns>
public bool ActivateScene(string location);
/// <summary>
/// 解除场景加载挂起操作。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否操作成功。</returns>
public bool UnSuspend(string location);
/// <summary>
/// 是否为主场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否主场景。</returns>
public bool IsMainScene(string location);
/// <summary>
/// 异步卸载子场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>场景卸载异步操作类。</returns>
public UnloadSceneOperation UnloadAsync(string location);
/// <summary>
/// 是否包含场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否包含场景。</returns>
public bool IsContainScene(string location);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f0b4f7a8db8740098bcb15904587e077
timeCreated: 1697614518

View File

@@ -0,0 +1,115 @@
using System;
using UnityEngine.SceneManagement;
using YooAsset;
namespace TEngine
{
/// <summary>
/// 场景管理模块。
/// </summary>
public sealed class SceneModule: Module
{
private ISceneModule _sceneModule;
private void Start()
{
RootModule baseComponent = ModuleSystem.GetModule<RootModule>();
if (baseComponent == null)
{
Log.Fatal("Root module is invalid.");
return;
}
_sceneModule = ModuleImpSystem.GetModule<SceneModuleImp>();
if (_sceneModule == null)
{
Log.Fatal("SceneModule is invalid.");
return;
}
}
/// <summary>
/// 当前主场景名称。
/// </summary>
public string CurrentMainSceneName => _sceneModule.CurrentMainSceneName;
/// <summary>
/// 加载场景。
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="suspendLoad">加载完毕时是否主动挂起</param>
/// <param name="priority">优先级</param>
/// <param name="callBack">加载回调。</param>
/// <param name="gcCollect">加载主场景是否回收垃圾。</param>
public void LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100,
Action<SceneOperationHandle> callBack = null, bool gcCollect = true)
{
_sceneModule.LoadScene(location, sceneMode, suspendLoad, priority, callBack, gcCollect);
}
/// <summary>
/// 加载子场景。
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="suspendLoad">加载完毕时是否主动挂起</param>
/// <param name="priority">优先级</param>
/// <param name="callBack">加载回调。</param>
/// <param name="gcCollect">加载主场景是否回收垃圾。</param>
public void LoadSubScene(string location, bool suspendLoad = false, int priority = 100,
Action<SceneOperationHandle> callBack = null, bool gcCollect = true)
{
_sceneModule.LoadScene(location, LoadSceneMode.Additive, suspendLoad, priority, callBack, gcCollect);
}
/// <summary>
/// 激活场景(当同时存在多个场景时用于切换激活场景)。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否操作成功。</returns>
public bool ActivateScene(string location)
{
return _sceneModule.ActivateScene(location);
}
/// <summary>
/// 解除场景加载挂起操作。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否操作成功。</returns>
public bool UnSuspend(string location)
{
return _sceneModule.UnSuspend(location);
}
/// <summary>
/// 是否为主场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否主场景。</returns>
public bool IsMainScene(string location)
{
return _sceneModule.IsMainScene(location);
}
/// <summary>
/// 异步卸载子场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>场景卸载异步操作类。</returns>
public UnloadSceneOperation UnloadAsync(string location)
{
return _sceneModule.UnloadAsync(location);
}
/// <summary>
/// 是否包含场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否包含场景。</returns>
public bool IsContainScene(string location)
{
return _sceneModule.IsContainScene(location);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 86342cc6845c403da1a3f6db507fae9d
timeCreated: 1697616931

View File

@@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using YooAsset;
namespace TEngine
{
/// <summary>
/// 场景管理器。
/// </summary>
internal class SceneModuleImp : ModuleImp,ISceneModule
{
private string _currentMainSceneName = string.Empty;
private SceneOperationHandle _currentMainScene;
private readonly Dictionary<string,SceneOperationHandle> _subScenes = new Dictionary<string, SceneOperationHandle>();
/// <summary>
/// 当前主场景名称。
/// </summary>
public string CurrentMainSceneName => _currentMainSceneName;
internal override void Shutdown()
{
var iter = _subScenes.Values.GetEnumerator();
while (iter.MoveNext())
{
SceneOperationHandle subScene = iter.Current;
if (subScene != null)
{
subScene.UnloadAsync();
}
}
iter.Dispose();
_subScenes.Clear();
_currentMainSceneName = string.Empty;
}
/// <summary>
/// 加载场景。
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="suspendLoad">加载完毕时是否主动挂起</param>
/// <param name="priority">优先级</param>
/// <param name="callBack">加载回调。</param>
/// <param name="gcCollect">加载主场景是否回收垃圾。</param>
public void LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100, Action<SceneOperationHandle> callBack = null,bool gcCollect = true)
{
if (sceneMode == LoadSceneMode.Additive)
{
if (_subScenes.ContainsKey(location))
{
Log.Warning($"Could not load subScene while already loaded. Scene: {location}");
return;
}
var subScene = GameModule.Resource.LoadSceneAsync(location, sceneMode, suspendLoad, priority);
if (callBack != null)
{
subScene.Completed += callBack;
}
_subScenes.Add(location, subScene);
}
else if(sceneMode == LoadSceneMode.Single)
{
_currentMainSceneName = location;
_currentMainScene = GameModule.Resource.LoadSceneAsync(location, sceneMode, suspendLoad, priority);
if (callBack != null)
{
_currentMainScene.Completed += callBack;
}
GameModule.Resource.ForceUnloadUnusedAssets(gcCollect);
}
}
/// <summary>
/// 激活场景(当同时存在多个场景时用于切换激活场景)。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否操作成功。</returns>
public bool ActivateScene(string location)
{
if (_currentMainSceneName.Equals(location))
{
if (_currentMainScene != null)
{
return _currentMainScene.ActivateScene();
}
return false;
}
_subScenes.TryGetValue(location, out SceneOperationHandle subScene);
if (subScene != null)
{
return subScene.ActivateScene();
}
Log.Warning($"IsMainScene invalid location:{location}");
return false;
}
/// <summary>
/// 解除场景加载挂起操作。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否操作成功。</returns>
public bool UnSuspend(string location)
{
if (_currentMainSceneName.Equals(location))
{
if (_currentMainScene != null)
{
return _currentMainScene.UnSuspend();
}
return false;
}
_subScenes.TryGetValue(location, out SceneOperationHandle subScene);
if (subScene != null)
{
return subScene.UnSuspend();
}
Log.Warning($"IsMainScene invalid location:{location}");
return false;
}
/// <summary>
/// 是否为主场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否主场景。</returns>
public bool IsMainScene(string location)
{
if (_currentMainSceneName.Equals(location))
{
if (_currentMainScene != null)
{
return _currentMainScene.IsMainScene();
}
return true;
}
_subScenes.TryGetValue(location, out SceneOperationHandle subScene);
if (subScene != null)
{
return subScene.IsMainScene();
}
Log.Warning($"IsMainScene invalid location:{location}");
return false;
}
/// <summary>
/// 异步卸载子场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>场景卸载异步操作类。</returns>
public UnloadSceneOperation UnloadAsync(string location)
{
_subScenes.TryGetValue(location, out SceneOperationHandle subScene);
if (subScene != null)
{
if (subScene.SceneObject == default)
{
Log.Error($"Could not unload Scene while not loaded. Scene: {location}");
return null;
}
_subScenes.Remove(location);
return subScene.UnloadAsync();
}
Log.Warning($"UnloadAsync invalid location:{location}");
return null;
}
/// <summary>
/// 是否包含场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <returns>是否包含场景。</returns>
public bool IsContainScene(string location)
{
if (_currentMainSceneName.Equals(location))
{
return true;
}
return _subScenes.TryGetValue(location, out var _);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 67fca5b8a8634d7b9e62c640a4049d02
timeCreated: 1697614527