diff --git a/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs b/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs index cb62f8e..9b17adc 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs @@ -10,28 +10,31 @@ namespace YooAsset { private static readonly List _loaders = new List(1000); private static readonly List _providers = new List(1000); + private static readonly HashSet _trackGameObjectHandles = new HashSet(); private static readonly Dictionary _sceneHandles = new Dictionary(100); private static bool _simulationOnEditor; private static int _loadingMaxNumber; + public static bool AutoReleaseGameObjectHandle { private set; get; } public static IDecryptionServices DecryptionServices { private set; get; } public static IBundleServices BundleServices { private set; get; } /// - /// 初始化资源系统 + /// 初始化 /// 注意:在使用AssetSystem之前需要初始化 /// - public static void Initialize(bool simulationOnEditor, int loadingMaxNumber, IDecryptionServices decryptionServices, IBundleServices bundleServices) + public static void Initialize(bool simulationOnEditor, int loadingMaxNumber, bool autoReleaseGameObjectHandle, IDecryptionServices decryptionServices, IBundleServices bundleServices) { _simulationOnEditor = simulationOnEditor; _loadingMaxNumber = loadingMaxNumber; + AutoReleaseGameObjectHandle = autoReleaseGameObjectHandle; DecryptionServices = decryptionServices; BundleServices = bundleServices; } /// - /// 轮询更新 + /// 更新 /// public static void Update() { @@ -81,6 +84,11 @@ namespace YooAsset /// public static void UnloadUnusedAssets() { + if (AutoReleaseGameObjectHandle) + { + CheckAutoReleaseGameObjectHandle(); + } + if (_simulationOnEditor) { for (int i = _providers.Count - 1; i >= 0; i--) @@ -221,6 +229,29 @@ namespace YooAsset return provider.CreateHandle(); } + /// + /// 添加自动释放的游戏对象句柄 + /// + public static void AddAutoReleaseGameObjectHandle(AssetOperationHandle handle) + { + if (_trackGameObjectHandles.Contains(handle) == false) + _trackGameObjectHandles.Add(handle); + } + private static void CheckAutoReleaseGameObjectHandle() + { + List removeList = new List(); + foreach (var trackHandle in _trackGameObjectHandles) + { + trackHandle.CheckAutoReleaseHandle(); + if (trackHandle.IsValidNoWarning == false) + removeList.Add(trackHandle); + } + foreach (var removeHandle in removeList) + { + _trackGameObjectHandles.Remove(removeHandle); + } + } + internal static void UnloadSubScene(ProviderBase provider) { string providerGUID = provider.MainAssetInfo.ProviderGUID; diff --git a/Assets/YooAsset/Runtime/AssetSystem/Handles/AssetOperationHandle.cs b/Assets/YooAsset/Runtime/AssetSystem/Handles/AssetOperationHandle.cs index c8349e8..bf58a61 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Handles/AssetOperationHandle.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Handles/AssetOperationHandle.cs @@ -1,4 +1,5 @@ using UnityEngine; +using System.Collections.Generic; namespace YooAsset { @@ -117,26 +118,72 @@ namespace YooAsset if (Provider.AssetObject == null) return null; + GameObject result; if (setPositionRotation) { if (parent == null) - return UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation); + result = UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation); else - return UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation, parent); + result = UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation, parent); } else { if (parent == null) - return UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject); + result = UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject); else - return UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, parent); + result = UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, parent); } + + if (AssetSystem.AutoReleaseGameObjectHandle) + { + AddTrackGameObject(result); + } + return result; } private InstantiateOperation InstantiateAsyncInternal(Vector3 position, Quaternion rotation, Transform parent, bool setPositionRotation) { InstantiateOperation operation = new InstantiateOperation(this, position, rotation, parent, setPositionRotation); OperationSystem.StartOperaiton(operation); + + if (AssetSystem.AutoReleaseGameObjectHandle) + { + operation.Completed += InstantiateOperationCompleted; + } return operation; } + + #region 资源对象句柄相关 + private readonly HashSet _trackGameObjects = new HashSet(); + private void InstantiateOperationCompleted(AsyncOperationBase obj) + { + if (obj.Status == EOperationStatus.Succeed) + { + var op = obj as InstantiateOperation; + AddTrackGameObject(op.Result); + } + } + private void AddTrackGameObject(GameObject go) + { + if (go != null) + { + _trackGameObjects.Add(go); + AssetSystem.AddAutoReleaseGameObjectHandle(this); + } + } + internal void CheckAutoReleaseHandle() + { + if (IsValidNoWarning == false) + return; + if (_trackGameObjects.Count == 0) + return; + + foreach (var go in _trackGameObjects) + { + if (go != null) + return; + } + ReleaseInternal(); + } + #endregion } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/AssetSystem/Handles/OperationHandleBase.cs b/Assets/YooAsset/Runtime/AssetSystem/Handles/OperationHandleBase.cs index 12a471a..5097643 100644 --- a/Assets/YooAsset/Runtime/AssetSystem/Handles/OperationHandleBase.cs +++ b/Assets/YooAsset/Runtime/AssetSystem/Handles/OperationHandleBase.cs @@ -93,6 +93,20 @@ namespace YooAsset } } + /// + /// 句柄是否有效 + /// + public bool IsValidNoWarning + { + get + { + if (Provider != null && Provider.IsDestroyed == false) + return true; + else + return false; + } + } + /// /// 释放句柄 /// diff --git a/Assets/YooAsset/Runtime/YooAssets.cs b/Assets/YooAsset/Runtime/YooAssets.cs index 9b8c325..9b8962d 100644 --- a/Assets/YooAsset/Runtime/YooAssets.cs +++ b/Assets/YooAsset/Runtime/YooAssets.cs @@ -40,6 +40,12 @@ namespace YooAsset /// public bool LocationToLower = false; + /// + /// 自动释放游戏对象所属资源句柄 + /// 说明:通过资源句柄实例化的游戏对象在销毁之后,会自动释放所属资源句柄。 + /// + public bool AutoReleaseGameObjectHandle = false; + /// /// 资源定位服务接口 /// @@ -208,7 +214,7 @@ namespace YooAsset { _editorSimulateModeImpl = new EditorSimulateModeImpl(); _bundleServices = _editorSimulateModeImpl; - AssetSystem.Initialize(true, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices); + AssetSystem.Initialize(true, parameters.AssetLoadingMaxNumber, parameters.AutoReleaseGameObjectHandle, parameters.DecryptionServices, _bundleServices); var editorSimulateModeParameters = parameters as EditorSimulateModeParameters; initializeOperation = _editorSimulateModeImpl.InitializeAsync( editorSimulateModeParameters.LocationToLower, @@ -218,14 +224,14 @@ namespace YooAsset { _offlinePlayModeImpl = new OfflinePlayModeImpl(); _bundleServices = _offlinePlayModeImpl; - AssetSystem.Initialize(false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices); + AssetSystem.Initialize(false, parameters.AssetLoadingMaxNumber, parameters.AutoReleaseGameObjectHandle, parameters.DecryptionServices, _bundleServices); initializeOperation = _offlinePlayModeImpl.InitializeAsync(parameters.LocationToLower); } else if (_playMode == EPlayMode.HostPlayMode) { _hostPlayModeImpl = new HostPlayModeImpl(); _bundleServices = _hostPlayModeImpl; - AssetSystem.Initialize(false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices); + AssetSystem.Initialize(false, parameters.AssetLoadingMaxNumber, parameters.AutoReleaseGameObjectHandle, parameters.DecryptionServices, _bundleServices); var hostPlayModeParameters = parameters as HostPlayModeParameters; initializeOperation = _hostPlayModeImpl.InitializeAsync( hostPlayModeParameters.LocationToLower,