Add AutoReleaseGameObjectHandle initialize parameters

支持自动释放游戏对象句柄的功能。
pull/17/head
hevinci 2022-06-23 16:02:53 +08:00
parent 60f6483a86
commit 32148821a1
4 changed files with 108 additions and 10 deletions

View File

@ -10,28 +10,31 @@ namespace YooAsset
{ {
private static readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000); private static readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000);
private static readonly List<ProviderBase> _providers = new List<ProviderBase>(1000); private static readonly List<ProviderBase> _providers = new List<ProviderBase>(1000);
private static readonly HashSet<AssetOperationHandle> _trackGameObjectHandles = new HashSet<AssetOperationHandle>();
private static readonly Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100); private static readonly Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100);
private static bool _simulationOnEditor; private static bool _simulationOnEditor;
private static int _loadingMaxNumber; private static int _loadingMaxNumber;
public static bool AutoReleaseGameObjectHandle { private set; get; }
public static IDecryptionServices DecryptionServices { private set; get; } public static IDecryptionServices DecryptionServices { private set; get; }
public static IBundleServices BundleServices { private set; get; } public static IBundleServices BundleServices { private set; get; }
/// <summary> /// <summary>
/// 初始化资源系统 /// 初始化
/// 注意在使用AssetSystem之前需要初始化 /// 注意在使用AssetSystem之前需要初始化
/// </summary> /// </summary>
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; _simulationOnEditor = simulationOnEditor;
_loadingMaxNumber = loadingMaxNumber; _loadingMaxNumber = loadingMaxNumber;
AutoReleaseGameObjectHandle = autoReleaseGameObjectHandle;
DecryptionServices = decryptionServices; DecryptionServices = decryptionServices;
BundleServices = bundleServices; BundleServices = bundleServices;
} }
/// <summary> /// <summary>
/// 轮询更新 /// 更新
/// </summary> /// </summary>
public static void Update() public static void Update()
{ {
@ -81,6 +84,11 @@ namespace YooAsset
/// </summary> /// </summary>
public static void UnloadUnusedAssets() public static void UnloadUnusedAssets()
{ {
if (AutoReleaseGameObjectHandle)
{
CheckAutoReleaseGameObjectHandle();
}
if (_simulationOnEditor) if (_simulationOnEditor)
{ {
for (int i = _providers.Count - 1; i >= 0; i--) for (int i = _providers.Count - 1; i >= 0; i--)
@ -221,6 +229,29 @@ namespace YooAsset
return provider.CreateHandle<SubAssetsOperationHandle>(); return provider.CreateHandle<SubAssetsOperationHandle>();
} }
/// <summary>
/// 添加自动释放的游戏对象句柄
/// </summary>
public static void AddAutoReleaseGameObjectHandle(AssetOperationHandle handle)
{
if (_trackGameObjectHandles.Contains(handle) == false)
_trackGameObjectHandles.Add(handle);
}
private static void CheckAutoReleaseGameObjectHandle()
{
List<AssetOperationHandle> removeList = new List<AssetOperationHandle>();
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) internal static void UnloadSubScene(ProviderBase provider)
{ {
string providerGUID = provider.MainAssetInfo.ProviderGUID; string providerGUID = provider.MainAssetInfo.ProviderGUID;

View File

@ -1,4 +1,5 @@
using UnityEngine; using UnityEngine;
using System.Collections.Generic;
namespace YooAsset namespace YooAsset
{ {
@ -117,26 +118,72 @@ namespace YooAsset
if (Provider.AssetObject == null) if (Provider.AssetObject == null)
return null; return null;
GameObject result;
if (setPositionRotation) if (setPositionRotation)
{ {
if (parent == null) if (parent == null)
return UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation); result = UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation);
else else
return UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation, parent); result = UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject, position, rotation, parent);
} }
else else
{ {
if (parent == null) if (parent == null)
return UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject); result = UnityEngine.Object.Instantiate(Provider.AssetObject as GameObject);
else 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) private InstantiateOperation InstantiateAsyncInternal(Vector3 position, Quaternion rotation, Transform parent, bool setPositionRotation)
{ {
InstantiateOperation operation = new InstantiateOperation(this, position, rotation, parent, setPositionRotation); InstantiateOperation operation = new InstantiateOperation(this, position, rotation, parent, setPositionRotation);
OperationSystem.StartOperaiton(operation); OperationSystem.StartOperaiton(operation);
if (AssetSystem.AutoReleaseGameObjectHandle)
{
operation.Completed += InstantiateOperationCompleted;
}
return operation; return operation;
} }
#region 资源对象句柄相关
private readonly HashSet<GameObject> _trackGameObjects = new HashSet<GameObject>();
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
} }
} }

View File

@ -93,6 +93,20 @@ namespace YooAsset
} }
} }
/// <summary>
/// 句柄是否有效
/// </summary>
public bool IsValidNoWarning
{
get
{
if (Provider != null && Provider.IsDestroyed == false)
return true;
else
return false;
}
}
/// <summary> /// <summary>
/// 释放句柄 /// 释放句柄
/// </summary> /// </summary>

View File

@ -40,6 +40,12 @@ namespace YooAsset
/// </summary> /// </summary>
public bool LocationToLower = false; public bool LocationToLower = false;
/// <summary>
/// 自动释放游戏对象所属资源句柄
/// 说明:通过资源句柄实例化的游戏对象在销毁之后,会自动释放所属资源句柄。
/// </summary>
public bool AutoReleaseGameObjectHandle = false;
/// <summary> /// <summary>
/// 资源定位服务接口 /// 资源定位服务接口
/// </summary> /// </summary>
@ -208,7 +214,7 @@ namespace YooAsset
{ {
_editorSimulateModeImpl = new EditorSimulateModeImpl(); _editorSimulateModeImpl = new EditorSimulateModeImpl();
_bundleServices = _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; var editorSimulateModeParameters = parameters as EditorSimulateModeParameters;
initializeOperation = _editorSimulateModeImpl.InitializeAsync( initializeOperation = _editorSimulateModeImpl.InitializeAsync(
editorSimulateModeParameters.LocationToLower, editorSimulateModeParameters.LocationToLower,
@ -218,14 +224,14 @@ namespace YooAsset
{ {
_offlinePlayModeImpl = new OfflinePlayModeImpl(); _offlinePlayModeImpl = new OfflinePlayModeImpl();
_bundleServices = _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); initializeOperation = _offlinePlayModeImpl.InitializeAsync(parameters.LocationToLower);
} }
else if (_playMode == EPlayMode.HostPlayMode) else if (_playMode == EPlayMode.HostPlayMode)
{ {
_hostPlayModeImpl = new HostPlayModeImpl(); _hostPlayModeImpl = new HostPlayModeImpl();
_bundleServices = _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; var hostPlayModeParameters = parameters as HostPlayModeParameters;
initializeOperation = _hostPlayModeImpl.InitializeAsync( initializeOperation = _hostPlayModeImpl.InitializeAsync(
hostPlayModeParameters.LocationToLower, hostPlayModeParameters.LocationToLower,