From 8944ec0e028c088f4c4ae56d9e5241968e54d00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E5=86=A0=E5=B3=B0?= Date: Fri, 27 Dec 2024 11:53:55 +0800 Subject: [PATCH] fix #419 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化场景卸载逻辑 --- .../ResourceManager/Handle/SceneHandle.cs | 30 ------ .../Operation/UnloadAllAssetsOperation.cs | 4 +- .../Operation/UnloadSceneOperation.cs | 15 ++- .../Provider/ProviderOperation.cs | 6 -- .../ResourceManager/Provider/SceneProvider.cs | 11 --- .../ResourceManager/ResourceManager.cs | 94 +++++++------------ .../ResourcePackage/ResourcePackage.cs | 15 ++- 7 files changed, 59 insertions(+), 116 deletions(-) diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs index fd2727f0..2acbff5f 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs @@ -112,25 +112,6 @@ namespace YooAsset return true; } - /// - /// 是否为主场景 - /// - public bool IsMainScene() - { - if (IsValidWithWarning == false) - return false; - - if (Provider is SceneProvider) - { - var temp = Provider as SceneProvider; - return temp.SceneMode == LoadSceneMode.Single; - } - else - { - throw new System.NotImplementedException(); - } - } - /// /// 异步卸载子场景 /// @@ -147,17 +128,6 @@ namespace YooAsset return operation; } - // 如果是主场景 - if (IsMainScene()) - { - string error = $"Cannot unload main scene. Use {nameof(YooAssets.LoadSceneAsync)} method to change the main scene !"; - YooLogger.Error(error); - var operation = new UnloadSceneOperation(error); - OperationSystem.StartOperation(packageName, operation); - return operation; - } - - // 卸载子场景 // 注意:如果场景正在加载过程,必须等待加载完成后才可以卸载该场景。 { var operation = new UnloadSceneOperation(Provider); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs index 659d4091..8cb5454a 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadAllAssetsOperation.cs @@ -58,6 +58,9 @@ namespace YooAsset var loaderDic = _resManager._loaderDic; var providerDic = _resManager._providerDic; + // 清空所有场景句柄 + _resManager._sceneHandles.Clear(); + // 释放所有资源句柄 foreach (var provider in providerDic.Values) { @@ -79,7 +82,6 @@ namespace YooAsset // 清空数据 providerDic.Clear(); loaderDic.Clear(); - _resManager.ClearSceneHandle(); // 注意:调用底层接口释放所有资源 Resources.UnloadUnusedAssets(); diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs index 8ed2d799..981b795d 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs @@ -12,7 +12,7 @@ namespace YooAsset { None, CheckError, - PrepareDone, + WaitDone, UnLoadScene, Done, } @@ -61,10 +61,10 @@ namespace YooAsset return; } - _steps = ESteps.PrepareDone; + _steps = ESteps.WaitDone; } - if (_steps == ESteps.PrepareDone) + if (_steps == ESteps.WaitDone) { if (_provider.IsDone == false) return; @@ -93,14 +93,19 @@ namespace YooAsset if (_asyncOp == null) { _asyncOp = SceneManager.UnloadSceneAsync(_provider.SceneObject); - _provider.ResourceMgr.UnloadSubScene(_provider.SceneName); + if (_asyncOp == null) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Unload scene failed, see the console logs !"; + return; + } } Progress = _asyncOp.progress; if (_asyncOp.isDone == false) return; - _provider.ResourceMgr.TryUnloadUnusedAsset(_provider.MainAssetInfo); _steps = ESteps.Done; Status = EOperationStatus.Succeed; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs index 21d9588b..260ad8a7 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs @@ -20,11 +20,6 @@ namespace YooAsset /// public string ProviderGUID { private set; get; } - /// - /// 所属资源系统 - /// - public ResourceManager ResourceMgr { private set; get; } - /// /// 资源信息 /// @@ -79,7 +74,6 @@ namespace YooAsset public ProviderOperation(ResourceManager manager, string providerGUID, AssetInfo assetInfo) { - ResourceMgr = manager; ProviderGUID = providerGUID; MainAssetInfo = assetInfo; diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs index 1a6f365d..791e05f9 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/SceneProvider.cs @@ -12,17 +12,6 @@ namespace YooAsset private bool _suspendLoad; private FSLoadSceneOperation _loadSceneOp; - /// - /// 场景加载模式 - /// - public LoadSceneMode SceneMode - { - get - { - return _loadParams.loadSceneMode; - } - } - public SceneProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad) : base(manager, providerGUID, assetInfo) { _loadParams = loadParams; diff --git a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs index 2cda07f4..b8ac7640 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs @@ -9,12 +9,10 @@ namespace YooAsset { internal class ResourceManager { - // 全局场景句柄集合 - private readonly static Dictionary _sceneHandles = new Dictionary(100); - private static long _sceneCreateCount = 0; - internal readonly Dictionary _providerDic = new Dictionary(5000); internal readonly Dictionary _loaderDic = new Dictionary(5000); + internal readonly List _sceneHandles = new List(100); + private long _sceneCreateIndex = 0; private IBundleQuery _bundleQuery; /// @@ -34,6 +32,15 @@ namespace YooAsset public void Initialize(InitializeParameters initializeParameters, IBundleQuery bundleServices) { _bundleQuery = bundleServices; + SceneManager.sceneUnloaded += OnSceneUnloaded; + } + + /// + /// 销毁管理器 + /// + public void Destroy() + { + SceneManager.sceneUnloaded -= OnSceneUnloaded; } /// @@ -93,14 +100,8 @@ namespace YooAsset return completedProvider.CreateHandle(); } - // 如果加载的是主场景,则卸载所有缓存的场景 - if (loadSceneParams.loadSceneMode == LoadSceneMode.Single) - { - UnloadAllScene(); - } - // 注意:同一个场景的ProviderGUID每次加载都会变化 - string providerGUID = $"{assetInfo.GUID}-{++_sceneCreateCount}"; + string providerGUID = $"{assetInfo.GUID}-{++_sceneCreateIndex}"; ProviderOperation provider; { provider = new SceneProvider(this, providerGUID, assetInfo, loadSceneParams, suspendLoad); @@ -112,7 +113,7 @@ namespace YooAsset provider.Priority = priority; var handle = provider.CreateHandle(); handle.PackageName = PackageName; - _sceneHandles.Add(providerGUID, handle); + _sceneHandles.Add(handle); return handle; } @@ -224,56 +225,6 @@ namespace YooAsset return provider.CreateHandle(); } - - internal void UnloadSubScene(string sceneName) - { - List removeKeys = new List(); - foreach (var valuePair in _sceneHandles) - { - var sceneHandle = valuePair.Value; - if (sceneHandle.SceneName == sceneName) - { - // 释放子场景句柄 - sceneHandle.ReleaseInternal(); - removeKeys.Add(valuePair.Key); - } - } - - foreach (string key in removeKeys) - { - _sceneHandles.Remove(key); - } - } - internal void UnloadAllScene() - { - // 释放所有场景句柄 - foreach (var valuePair in _sceneHandles) - { - valuePair.Value.ReleaseInternal(); - } - _sceneHandles.Clear(); - } - internal void ClearSceneHandle() - { - // 释放资源包下的所有场景 - if (_bundleQuery.ManifestValid()) - { - string packageName = PackageName; - List removeList = new List(); - foreach (var valuePair in _sceneHandles) - { - if (valuePair.Value.PackageName == packageName) - { - removeList.Add(valuePair.Key); - } - } - foreach (var key in removeList) - { - _sceneHandles.Remove(key); - } - } - } - internal LoadBundleFileOperation CreateMainBundleFileLoader(AssetInfo assetInfo) { BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo); @@ -330,6 +281,25 @@ namespace YooAsset else return null; } + private void OnSceneUnloaded(Scene scene) + { + List removeList = new List(); + foreach (var sceneHandle in _sceneHandles) + { + if (sceneHandle.IsValid) + { + if (sceneHandle.SceneObject == scene) + { + sceneHandle.ReleaseInternal(); + removeList.Add(sceneHandle); + } + } + } + foreach (var sceneHandle in removeList) + { + _sceneHandles.Remove(sceneHandle); + } + } #region 调试信息 internal List GetDebugReportInfos() diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs index 4e8768a2..0342e6f6 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs @@ -57,7 +57,13 @@ namespace YooAsset _initializeError = string.Empty; _initializeStatus = EOperationStatus.None; - _resourceManager = null; + // 销毁资源管理器 + if (_resourceManager != null) + { + _resourceManager.Destroy(); + _resourceManager = null; + } + _bundleQuery = null; _playModeImpl = null; } @@ -74,6 +80,13 @@ namespace YooAsset // 检测初始化参数合法性 CheckInitializeParameters(parameters); + // 销毁资源管理器 + if (_resourceManager != null) + { + _resourceManager.Destroy(); + _resourceManager = null; + } + // 创建资源管理器 InitializationOperation initializeOperation; _resourceManager = new ResourceManager(PackageName);