From 36db2f3abaa156ee322aff36c4393a4c16eddbc6 Mon Sep 17 00:00:00 2001 From: Alex-Rachel <574809918@qq.com> Date: Wed, 19 Mar 2025 09:30:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0UnLoadAsync,=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4LoadSceneAsync=E7=9A=84=E5=91=BD=E5=90=8D=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=5FhandlingScene=E5=BD=93=E5=89=8D=E6=AD=A3?= =?UTF-8?q?=E5=9C=A8=E5=A4=84=E7=90=86=E7=9A=84Scene=E4=BF=9D=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加UnLoadAsync, 调整LoadSceneAsync的命名,增加_handlingScene当前正在处理的Scene保护 --- .../Module/SceneModule/ISceneModule.cs | 11 +- .../Runtime/Module/SceneModule/SceneModule.cs | 103 ++++++++++++++++-- 2 files changed, 103 insertions(+), 11 deletions(-) diff --git a/UnityProject/Assets/TEngine/Runtime/Module/SceneModule/ISceneModule.cs b/UnityProject/Assets/TEngine/Runtime/Module/SceneModule/ISceneModule.cs index 26ab0dff..33759d9e 100644 --- a/UnityProject/Assets/TEngine/Runtime/Module/SceneModule/ISceneModule.cs +++ b/UnityProject/Assets/TEngine/Runtime/Module/SceneModule/ISceneModule.cs @@ -20,7 +20,7 @@ namespace TEngine /// 优先级 /// 加载主场景是否回收垃圾。 /// 加载进度回调。 - public UniTask LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, + public UniTask LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, Action progressCallBack = null); /// @@ -62,13 +62,20 @@ namespace TEngine /// 是否主场景。 public bool IsMainScene(string location); + /// + /// 异步卸载子场景。 + /// + /// 场景资源定位地址。 + /// 进度回调。 + public UniTask UnloadAsync(string location, Action progressCallBack = null); + /// /// 异步卸载子场景。 /// /// 场景资源定位地址。 /// 卸载完成回调。 /// 进度回调。 - public void UnloadAsync(string location, Action callBack = null, Action progressCallBack = null); + public void Unload(string location, Action callBack = null, Action progressCallBack = null); /// /// 是否包含场景。 diff --git a/UnityProject/Assets/TEngine/Runtime/Module/SceneModule/SceneModule.cs b/UnityProject/Assets/TEngine/Runtime/Module/SceneModule/SceneModule.cs index 8bd6b93d..47f1d257 100644 --- a/UnityProject/Assets/TEngine/Runtime/Module/SceneModule/SceneModule.cs +++ b/UnityProject/Assets/TEngine/Runtime/Module/SceneModule/SceneModule.cs @@ -13,6 +13,8 @@ namespace TEngine private SceneHandle _currentMainScene; private readonly Dictionary _subScenes = new Dictionary(); + + private readonly HashSet _handlingScene = new HashSet(); /// /// 当前主场景名称。 @@ -39,6 +41,7 @@ namespace TEngine iter.Dispose(); _subScenes.Clear(); + _handlingScene.Clear(); _currentMainSceneName = string.Empty; } @@ -51,8 +54,14 @@ namespace TEngine /// 优先级 /// 加载主场景是否回收垃圾。 /// 加载进度回调。 - public async UniTask LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, Action progressCallBack = null) + public async UniTask LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, Action progressCallBack = null) { + if (!_handlingScene.Add(location)) + { + Log.Error($"Could not load scene while loading. Scene: {location}"); + return default; + } + if (sceneMode == LoadSceneMode.Additive) { if (_subScenes.TryGetValue(location, out SceneHandle subScene)) @@ -62,7 +71,6 @@ namespace TEngine subScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority); - if (progressCallBack != null) { while (!subScene.IsDone && subScene.IsValid) @@ -78,6 +86,8 @@ namespace TEngine _subScenes.Add(location, subScene); + _handlingScene.Remove(location); + return subScene.SceneObject; } else @@ -103,9 +113,11 @@ namespace TEngine { await _currentMainScene.ToUniTask(); } - + ModuleSystem.GetModule().ForceUnloadUnusedAssets(gcCollect); + _handlingScene.Remove(location); + return _currentMainScene.SceneObject; } } @@ -124,6 +136,13 @@ namespace TEngine Action callBack = null, bool gcCollect = true, Action progressCallBack = null) { + + if (!_handlingScene.Add(location)) + { + Log.Error($"Could not load scene while loading. Scene: {location}"); + return; + } + if (sceneMode == LoadSceneMode.Additive) { if (_subScenes.TryGetValue(location, out SceneHandle subScene)) @@ -136,7 +155,11 @@ namespace TEngine if (callBack != null) { - subScene.Completed += handle => { callBack.Invoke(handle.SceneObject); }; + subScene.Completed += handle => + { + _handlingScene.Remove(location); + callBack.Invoke(handle.SceneObject); + }; } if (progressCallBack != null) @@ -160,7 +183,11 @@ namespace TEngine if (callBack != null) { - _currentMainScene.Completed += handle => { callBack.Invoke(handle.SceneObject); }; + _currentMainScene.Completed += handle => + { + _handlingScene.Remove(location); + callBack.Invoke(handle.SceneObject); + }; } if (progressCallBack != null) @@ -277,13 +304,61 @@ namespace TEngine return false; } + /// + /// 异步卸载子场景。 + /// + /// 场景资源定位地址。 + /// 进度回调。 + public async UniTask UnloadAsync(string location, Action progressCallBack = null) + { + _subScenes.TryGetValue(location, out SceneHandle subScene); + if (subScene != null) + { + if (subScene.SceneObject == default) + { + Log.Error($"Could not unload Scene while not loaded. Scene: {location}"); + return false; + } + + if (!_handlingScene.Add(location)) + { + Log.Warning($"Could not unload Scene while loading. Scene: {location}"); + return false; + } + + var unloadOperation = subScene.UnloadAsync(); + + if (progressCallBack != null) + { + while (!unloadOperation.IsDone && unloadOperation.Status != EOperationStatus.Failed) + { + progressCallBack.Invoke(unloadOperation.Progress); + await UniTask.Yield(); + } + } + else + { + await unloadOperation.ToUniTask(); + } + + _subScenes.Remove(location); + + _handlingScene.Remove(location); + + return true; + } + + Log.Warning($"UnloadAsync invalid location:{location}"); + return false; + } + /// /// 异步卸载子场景。 /// /// 场景资源定位地址。 /// 卸载完成回调。 /// 进度回调。 - public void UnloadAsync(string location, Action callBack = null, Action progressCallBack = null) + public void Unload(string location, Action callBack = null, Action progressCallBack = null) { _subScenes.TryGetValue(location, out SceneHandle subScene); if (subScene != null) @@ -293,19 +368,29 @@ namespace TEngine Log.Error($"Could not unload Scene while not loaded. Scene: {location}"); return; } + + if (!_handlingScene.Add(location)) + { + Log.Warning($"Could not unload Scene while loading. Scene: {location}"); + return; + } - _subScenes.Remove(location); subScene.UnloadAsync(); if (callBack != null) { - subScene.UnloadAsync().Completed += @base => { callBack.Invoke(); }; + subScene.UnloadAsync().Completed += @base => + { + _subScenes.Remove(location); + _handlingScene.Remove(location); + callBack.Invoke(); + }; } if (progressCallBack != null) { InvokeProgress(subScene, progressCallBack).Forget(); } - + return; }