diff --git a/UnityProject/Assets/Scenes/main.unity b/UnityProject/Assets/Scenes/main.unity index 28500b8f..0f6b994c 100644 --- a/UnityProject/Assets/Scenes/main.unity +++ b/UnityProject/Assets/Scenes/main.unity @@ -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: diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/GameModule.cs b/UnityProject/Assets/TEngine/Runtime/Modules/GameModule.cs index 66a006a6..2c8bdf90 100644 --- a/UnityProject/Assets/TEngine/Runtime/Modules/GameModule.cs +++ b/UnityProject/Assets/TEngine/Runtime/Modules/GameModule.cs @@ -82,6 +82,12 @@ namespace TEngine private static LocalizationModule _localization; + /// + /// 获取场景模块。 + /// + public static SceneModule Scene => _scene ??= Get(); + + private static SceneModule _scene; #endregion /// diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule.meta b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule.meta new file mode 100644 index 00000000..a02999fe --- /dev/null +++ b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2c67061fae264c5a861a5bdb257128a2 +timeCreated: 1697614501 \ No newline at end of file diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/ISceneModule.cs b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/ISceneModule.cs new file mode 100644 index 00000000..bbad129e --- /dev/null +++ b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/ISceneModule.cs @@ -0,0 +1,61 @@ +using System; +using UnityEngine.SceneManagement; +using YooAsset; + +namespace TEngine +{ + public interface ISceneModule + { + /// + /// 当前主场景名称。 + /// + public string CurrentMainSceneName { get; } + + /// + /// 加载场景。 + /// + /// 场景的定位地址 + /// 场景加载模式 + /// 加载完毕时是否主动挂起 + /// 优先级 + /// 加载回调。 + /// 加载主场景是否回收垃圾。 + public void LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100, + Action callBack = null, bool gcCollect = true); + + /// + /// 激活场景(当同时存在多个场景时用于切换激活场景)。 + /// + /// 场景资源定位地址。 + /// 是否操作成功。 + public bool ActivateScene(string location); + + /// + /// 解除场景加载挂起操作。 + /// + /// 场景资源定位地址。 + /// 是否操作成功。 + public bool UnSuspend(string location); + + /// + /// 是否为主场景。 + /// + /// 场景资源定位地址。 + /// 是否主场景。 + public bool IsMainScene(string location); + + /// + /// 异步卸载子场景。 + /// + /// 场景资源定位地址。 + /// 场景卸载异步操作类。 + public UnloadSceneOperation UnloadAsync(string location); + + /// + /// 是否包含场景。 + /// + /// 场景资源定位地址。 + /// 是否包含场景。 + public bool IsContainScene(string location); + } +} \ No newline at end of file diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/ISceneModule.cs.meta b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/ISceneModule.cs.meta new file mode 100644 index 00000000..df6f62c1 --- /dev/null +++ b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/ISceneModule.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f0b4f7a8db8740098bcb15904587e077 +timeCreated: 1697614518 \ No newline at end of file diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModule.cs b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModule.cs new file mode 100644 index 00000000..11329d48 --- /dev/null +++ b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModule.cs @@ -0,0 +1,115 @@ +using System; +using UnityEngine.SceneManagement; +using YooAsset; + +namespace TEngine +{ + /// + /// 场景管理模块。 + /// + public sealed class SceneModule: Module + { + private ISceneModule _sceneModule; + + private void Start() + { + RootModule baseComponent = ModuleSystem.GetModule(); + if (baseComponent == null) + { + Log.Fatal("Root module is invalid."); + return; + } + + _sceneModule = ModuleImpSystem.GetModule(); + if (_sceneModule == null) + { + Log.Fatal("SceneModule is invalid."); + return; + } + } + + /// + /// 当前主场景名称。 + /// + public string CurrentMainSceneName => _sceneModule.CurrentMainSceneName; + + /// + /// 加载场景。 + /// + /// 场景的定位地址 + /// 场景加载模式 + /// 加载完毕时是否主动挂起 + /// 优先级 + /// 加载回调。 + /// 加载主场景是否回收垃圾。 + public void LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100, + Action callBack = null, bool gcCollect = true) + { + _sceneModule.LoadScene(location, sceneMode, suspendLoad, priority, callBack, gcCollect); + } + + /// + /// 加载子场景。 + /// + /// 场景的定位地址 + /// 加载完毕时是否主动挂起 + /// 优先级 + /// 加载回调。 + /// 加载主场景是否回收垃圾。 + public void LoadSubScene(string location, bool suspendLoad = false, int priority = 100, + Action callBack = null, bool gcCollect = true) + { + _sceneModule.LoadScene(location, LoadSceneMode.Additive, suspendLoad, priority, callBack, gcCollect); + } + + /// + /// 激活场景(当同时存在多个场景时用于切换激活场景)。 + /// + /// 场景资源定位地址。 + /// 是否操作成功。 + public bool ActivateScene(string location) + { + return _sceneModule.ActivateScene(location); + } + + /// + /// 解除场景加载挂起操作。 + /// + /// 场景资源定位地址。 + /// 是否操作成功。 + public bool UnSuspend(string location) + { + return _sceneModule.UnSuspend(location); + } + + /// + /// 是否为主场景。 + /// + /// 场景资源定位地址。 + /// 是否主场景。 + public bool IsMainScene(string location) + { + return _sceneModule.IsMainScene(location); + } + + /// + /// 异步卸载子场景。 + /// + /// 场景资源定位地址。 + /// 场景卸载异步操作类。 + public UnloadSceneOperation UnloadAsync(string location) + { + return _sceneModule.UnloadAsync(location); + } + + /// + /// 是否包含场景。 + /// + /// 场景资源定位地址。 + /// 是否包含场景。 + public bool IsContainScene(string location) + { + return _sceneModule.IsContainScene(location); + } + } +} \ No newline at end of file diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModule.cs.meta b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModule.cs.meta new file mode 100644 index 00000000..b4365d7b --- /dev/null +++ b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModule.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 86342cc6845c403da1a3f6db507fae9d +timeCreated: 1697616931 \ No newline at end of file diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModuleImp.cs b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModuleImp.cs new file mode 100644 index 00000000..8be05993 --- /dev/null +++ b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModuleImp.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using UnityEngine.SceneManagement; +using YooAsset; + +namespace TEngine +{ + /// + /// 场景管理器。 + /// + internal class SceneModuleImp : ModuleImp,ISceneModule + { + private string _currentMainSceneName = string.Empty; + + private SceneOperationHandle _currentMainScene; + + private readonly Dictionary _subScenes = new Dictionary(); + + /// + /// 当前主场景名称。 + /// + 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; + } + + /// + /// 加载场景。 + /// + /// 场景的定位地址 + /// 场景加载模式 + /// 加载完毕时是否主动挂起 + /// 优先级 + /// 加载回调。 + /// 加载主场景是否回收垃圾。 + public void LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100, Action 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); + } + } + + /// + /// 激活场景(当同时存在多个场景时用于切换激活场景)。 + /// + /// 场景资源定位地址。 + /// 是否操作成功。 + 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; + } + + /// + /// 解除场景加载挂起操作。 + /// + /// 场景资源定位地址。 + /// 是否操作成功。 + 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; + } + + /// + /// 是否为主场景。 + /// + /// 场景资源定位地址。 + /// 是否主场景。 + 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; + } + + /// + /// 异步卸载子场景。 + /// + /// 场景资源定位地址。 + /// 场景卸载异步操作类。 + 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; + } + + /// + /// 是否包含场景。 + /// + /// 场景资源定位地址。 + /// 是否包含场景。 + public bool IsContainScene(string location) + { + if (_currentMainSceneName.Equals(location)) + { + return true; + } + return _subScenes.TryGetValue(location, out var _); + } + } +} \ No newline at end of file diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModuleImp.cs.meta b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModuleImp.cs.meta new file mode 100644 index 00000000..3b59d24a --- /dev/null +++ b/UnityProject/Assets/TEngine/Runtime/Modules/SceneModule/SceneModuleImp.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 67fca5b8a8634d7b9e62c640a4049d02 +timeCreated: 1697614527 \ No newline at end of file