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;
}