TEngine 6

This commit is contained in:
Alex-Rachel
2025-03-07 23:09:46 +08:00
parent aad8ff3ee5
commit 551727687f
1988 changed files with 46223 additions and 94880 deletions

View File

@@ -7,7 +7,9 @@ namespace YooAsset
private enum ESteps
{
None,
Clone,
LoadObject,
CloneSync,
CloneAsync,
Done,
}
@@ -17,15 +19,21 @@ namespace YooAsset
private readonly Quaternion _rotation;
private readonly Transform _parent;
private readonly bool _worldPositionStays;
private readonly bool _actived;
private ESteps _steps = ESteps.None;
#if UNITY_2023_3_OR_NEWER
private AsyncInstantiateOperation _instantiateAsync;
#endif
/// <summary>
/// 实例化的游戏对象
/// </summary>
public GameObject Result = null;
internal InstantiateOperation(AssetHandle handle, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
internal InstantiateOperation(AssetHandle handle, bool setPositionAndRotation, Vector3 position, Quaternion rotation,
Transform parent, bool worldPositionStays, bool actived)
{
_handle = handle;
_setPositionAndRotation = setPositionAndRotation;
@@ -33,17 +41,18 @@ namespace YooAsset
_rotation = rotation;
_parent = parent;
_worldPositionStays = worldPositionStays;
_actived = actived;
}
internal override void InternalOnStart()
internal override void InternalStart()
{
_steps = ESteps.Clone;
_steps = ESteps.LoadObject;
}
internal override void InternalOnUpdate()
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.Clone)
if (_steps == ESteps.LoadObject)
{
if (_handle.IsValidWithWarning == false)
{
@@ -64,12 +73,88 @@ namespace YooAsset
return;
}
#if UNITY_2023_3_OR_NEWER
//TODO 官方BUG
// BUG环境Windows平台Unity2022.3.41f1版本,编辑器模式。
// BUG描述异步实例化Prefab预制体有概率丢失Mono脚本里序列化的数组里某个成员
//_steps = ESteps.CloneAsync;
_steps = ESteps.CloneSync;
#else
_steps = ESteps.CloneSync;
#endif
}
if (_steps == ESteps.CloneSync)
{
// 实例化游戏对象
Result = InstantiateInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays);
if (_actived == false)
Result.SetActive(false);
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
#if UNITY_2023_3_OR_NEWER
if (_steps == ESteps.CloneAsync)
{
if (_instantiateAsync == null)
{
_instantiateAsync = InstantiateAsyncInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays);
}
if (IsWaitForAsyncComplete)
_instantiateAsync.WaitForCompletion();
if (_instantiateAsync.isDone == false)
return;
if (_instantiateAsync.Result != null && _instantiateAsync.Result.Length > 0)
{
Result = _instantiateAsync.Result[0] as GameObject;
if (Result != null)
{
if (_actived == false)
Result.SetActive(false);
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Instantiate game object is null !";
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Instantiate async results is null !";
}
}
#endif
}
internal override void InternalWaitForAsyncComplete()
{
while (true)
{
// 等待句柄完成
if (_handle != null)
_handle.WaitForAsyncComplete();
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
}
internal override string InternalGetDesc()
{
var assetInfo = _handle.GetAssetInfo();
return $"AssetPath : {assetInfo.AssetPath}";
}
/// <summary>
@@ -77,25 +162,17 @@ namespace YooAsset
/// </summary>
public void Cancel()
{
if (IsDone == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"User cancelled !";
}
#if UNITY_2023_3_OR_NEWER
if (_instantiateAsync != null && _instantiateAsync.isDone == false)
_instantiateAsync.Cancel();
#endif
AbortOperation();
}
/// <summary>
/// 等待异步实例化结束
/// 步实例化
/// </summary>
public void WaitForAsyncComplete()
{
if (_steps == ESteps.Done)
return;
_handle.WaitForAsyncComplete();
InternalOnUpdate();
}
internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
if (assetObject == null)
@@ -104,29 +181,42 @@ namespace YooAsset
if (setPositionAndRotation)
{
if (parent != null)
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent);
return clone;
}
return UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent);
else
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation);
return clone;
}
return UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation);
}
else
{
if (parent != null)
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays);
return clone;
}
return UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays);
else
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject);
return clone;
}
return UnityEngine.Object.Instantiate(assetObject as GameObject);
}
}
#if UNITY_2023_3_OR_NEWER
/// <summary>
/// 异步实例化
/// 注意Unity2022.3.20f1及以上版本生效
/// https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Object.InstantiateAsync.html
/// </summary>
internal static AsyncInstantiateOperation InstantiateAsyncInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
if (setPositionAndRotation)
{
if (parent != null)
return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, parent, position, rotation);
else
return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, position, rotation);
}
else
{
if (parent != null)
return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, parent);
else
return UnityEngine.Object.InstantiateAsync(assetObject as GameObject);
}
}
#endif
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dfb81dc2664ed4d4db4bd2b95caadae4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,222 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace YooAsset
{
internal class LoadBundleFileOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadFile,
Done,
}
private readonly ResourceManager _resourceManager;
private readonly List<ProviderOperation> _providers = new List<ProviderOperation>(100);
private readonly List<ProviderOperation> _removeList = new List<ProviderOperation>(100);
private FSLoadBundleOperation _loadBundleOp;
private ESteps _steps = ESteps.None;
/// <summary>
/// 资源包文件信息
/// </summary>
public BundleInfo LoadBundleInfo { private set; get; }
/// <summary>
/// 是否已经销毁
/// </summary>
public bool IsDestroyed { private set; get; } = false;
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; } = 0;
/// <summary>
/// 下载进度
/// </summary>
public float DownloadProgress { set; get; } = 0;
/// <summary>
/// 下载大小
/// </summary>
public long DownloadedBytes { set; get; } = 0;
/// <summary>
/// 加载结果
/// </summary>
public BundleResult Result { set; get; }
internal LoadBundleFileOperation(ResourceManager resourceManager, BundleInfo bundleInfo)
{
_resourceManager = resourceManager;
LoadBundleInfo = bundleInfo;
}
internal override void InternalStart()
{
_steps = ESteps.LoadFile;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadFile)
{
if (_loadBundleOp == null)
{
_loadBundleOp = LoadBundleInfo.LoadBundleFile();
_loadBundleOp.StartOperation();
AddChildOperation(_loadBundleOp);
}
if (IsWaitForAsyncComplete)
_loadBundleOp.WaitForAsyncComplete();
_loadBundleOp.UpdateOperation();
DownloadProgress = _loadBundleOp.DownloadProgress;
DownloadedBytes = _loadBundleOp.DownloadedBytes;
if (_loadBundleOp.IsDone == false)
return;
if (_loadBundleOp.Status == EOperationStatus.Succeed)
{
if (_loadBundleOp.Result == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The bundle loader result is null ! {LoadBundleInfo.Bundle.BundleName}";
}
else
{
_steps = ESteps.Done;
Result = _loadBundleOp.Result;
Status = EOperationStatus.Succeed;
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadBundleOp.Error;
}
}
}
internal override void InternalWaitForAsyncComplete()
{
while (true)
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
}
internal override string InternalGetDesc()
{
return $"BundleName : {LoadBundleInfo.Bundle.BundleName}";
}
/// <summary>
/// 引用(引用计数递加)
/// </summary>
public void Reference()
{
RefCount++;
}
/// <summary>
/// 释放(引用计数递减)
/// </summary>
public void Release()
{
RefCount--;
}
/// <summary>
/// 销毁
/// </summary>
public void DestroyLoader()
{
IsDestroyed = true;
// Check fatal
if (RefCount > 0)
throw new Exception($"Bundle file loader ref is not zero : {LoadBundleInfo.Bundle.BundleName}");
if (IsDone == false)
throw new Exception($"Bundle file loader is not done : {LoadBundleInfo.Bundle.BundleName}");
if (Result != null)
Result.UnloadBundleFile();
}
/// <summary>
/// 是否可以销毁
/// </summary>
public bool CanDestroyLoader()
{
if (IsDone == false)
return false;
if (RefCount > 0)
return false;
// YOOASSET_LEGACY_DEPENDENCY
// 检查引用链上的资源包是否已经全部销毁
// 注意:互相引用的资源包无法卸载!
if (LoadBundleInfo.Bundle.ReferenceBundleIDs.Count > 0)
{
foreach (var bundleID in LoadBundleInfo.Bundle.ReferenceBundleIDs)
{
if (_resourceManager.CheckBundleDestroyed(bundleID) == false)
return false;
}
}
return true;
}
/// <summary>
/// 添加附属的资源提供者
/// </summary>
public void AddProvider(ProviderOperation provider)
{
if (_providers.Contains(provider) == false)
_providers.Add(provider);
}
/// <summary>
/// 尝试销毁资源提供者
/// </summary>
public void TryDestroyProviders()
{
// 获取移除列表
_removeList.Clear();
foreach (var provider in _providers)
{
if (provider.CanDestroyProvider())
{
_removeList.Add(provider);
}
}
// 销毁资源提供者
foreach (var provider in _removeList)
{
_providers.Remove(provider);
provider.DestroyProvider();
}
// 移除资源提供者
if (_removeList.Count > 0)
{
_resourceManager.RemoveBundleProviders(_removeList);
_removeList.Clear();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 031287bf937f83e4fa18a0db797abb42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,132 @@
using System;
using UnityEngine;
namespace YooAsset
{
public sealed class UnloadAllAssetsOptions
{
/// <summary>
/// 释放所有资源句柄,防止卸载过程中触发完成回调!
/// </summary>
public bool ReleaseAllHandles = false;
/// <summary>
/// 卸载过程中锁定加载操作,防止新的任务请求!
/// </summary>
public bool LockLoadOperation = false;
}
public sealed class UnloadAllAssetsOperation : AsyncOperationBase
{
private enum ESteps
{
None,
CheckOptions,
ReleaseAll,
AbortDownload,
CheckLoading,
DestroyAll,
Done,
}
private readonly ResourceManager _resManager;
private readonly UnloadAllAssetsOptions _options;
private ESteps _steps = ESteps.None;
internal UnloadAllAssetsOperation(ResourceManager resourceManager, UnloadAllAssetsOptions options)
{
_resManager = resourceManager;
_options = options;
}
internal override void InternalStart()
{
_steps = ESteps.CheckOptions;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckOptions)
{
if (_options == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(UnloadAllAssetsOptions)} is null.";
return;
}
// 设置锁定状态
if (_options.LockLoadOperation)
_resManager.LockLoadOperation = true;
_steps = ESteps.ReleaseAll;
}
if (_steps == ESteps.ReleaseAll)
{
// 清空所有场景句柄
_resManager.SceneHandles.Clear();
// 释放所有资源句柄
if (_options.ReleaseAllHandles)
{
foreach (var provider in _resManager.ProviderDic.Values)
{
provider.ReleaseAllHandles();
}
}
_steps = ESteps.AbortDownload;
}
if (_steps == ESteps.AbortDownload)
{
// 注意:终止所有下载任务
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.AbortOperation();
}
_steps = ESteps.CheckLoading;
}
if (_steps == ESteps.CheckLoading)
{
// 注意:等待所有任务完成
foreach (var provider in _resManager.ProviderDic.Values)
{
if (provider.IsDone == false)
return;
}
_steps = ESteps.DestroyAll;
}
if (_steps == ESteps.DestroyAll)
{
// 强制销毁资源提供者
foreach (var provider in _resManager.ProviderDic.Values)
{
provider.DestroyProvider();
}
// 强制销毁文件加载器
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.DestroyLoader();
}
// 清空数据
_resManager.ProviderDic.Clear();
_resManager.LoaderDic.Clear();
_resManager.LockLoadOperation = false;
// 注意:调用底层接口释放所有资源
Resources.UnloadUnusedAssets();
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 97b5f55d30137a4438d3cbed93819c6b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -12,35 +12,29 @@ namespace YooAsset
{
None,
CheckError,
PrepareDone,
WaitDone,
UnLoadScene,
Checking,
Done,
}
private ESteps _steps = ESteps.None;
private readonly string _error;
private readonly ProviderBase _provider;
private AsyncOperation _asyncOp;
private readonly ProviderOperation _provider;
private AsyncOperation _asyncOp = null;
internal UnloadSceneOperation(string error)
{
_error = error;
}
internal UnloadSceneOperation(ProviderBase provider)
internal UnloadSceneOperation(ProviderOperation provider)
{
_error = null;
_provider = provider;
// 注意:卸载场景前必须先解除挂起操作
if (provider is DatabaseSceneProvider)
if (provider is SceneProvider)
{
var temp = provider as DatabaseSceneProvider;
temp.UnSuspendLoad();
}
else if (provider is BundledSceneProvider)
{
var temp = provider as BundledSceneProvider;
var temp = provider as SceneProvider;
temp.UnSuspendLoad();
}
else
@@ -48,11 +42,11 @@ namespace YooAsset
throw new System.NotImplementedException();
}
}
internal override void InternalOnStart()
internal override void InternalStart()
{
_steps = ESteps.CheckError;
}
internal override void InternalOnUpdate()
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
@@ -67,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;
@@ -96,20 +90,29 @@ namespace YooAsset
if (_steps == ESteps.UnLoadScene)
{
_asyncOp = SceneManager.UnloadSceneAsync(_provider.SceneObject);
_provider.ResourceMgr.UnloadSubScene(_provider.SceneName);
_steps = ESteps.Checking;
}
if (_asyncOp == null)
{
_asyncOp = SceneManager.UnloadSceneAsync(_provider.SceneObject);
if (_asyncOp == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Unload scene failed, see the console logs !";
return;
}
}
if (_steps == ESteps.Checking)
{
Progress = _asyncOp.progress;
if (_asyncOp.isDone == false)
return;
_provider.ResourceMgr.TryUnloadUnusedAsset(_provider.MainAssetInfo);
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
internal override string InternalGetDesc()
{
return $"SceneName : {_provider.SceneName}";
}
}
}

View File

@@ -0,0 +1,92 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
public sealed class UnloadUnusedAssetsOperation : AsyncOperationBase
{
private enum ESteps
{
None,
UnloadUnused,
Done,
}
private readonly ResourceManager _resManager;
private readonly int _loopCount;
private ESteps _steps = ESteps.None;
internal UnloadUnusedAssetsOperation(ResourceManager resourceManager, int loopCount)
{
_resManager = resourceManager;
_loopCount = loopCount;
}
internal override void InternalStart()
{
_steps = ESteps.UnloadUnused;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.UnloadUnused)
{
for (int i = 0; i < _loopCount; i++)
{
LoopUnloadUnused();
}
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
internal override void InternalWaitForAsyncComplete()
{
while (true)
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
}
internal override string InternalGetDesc()
{
return $"LoopCount : {_loopCount}";
}
/// <summary>
/// 说明:资源包之间会有深层的依赖链表,需要多次迭代才可以在单帧内卸载!
/// </summary>
private void LoopUnloadUnused()
{
var removeList = new List<LoadBundleFileOperation>(_resManager.LoaderDic.Count);
// 注意:优先销毁资源提供者
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.TryDestroyProviders();
}
// 获取销毁列表
foreach (var loader in _resManager.LoaderDic.Values)
{
if (loader.CanDestroyLoader())
{
removeList.Add(loader);
}
}
// 销毁文件加载器
foreach (var loader in removeList)
{
string bundleName = loader.LoadBundleInfo.Bundle.BundleName;
loader.DestroyLoader();
_resManager.LoaderDic.Remove(bundleName);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 90a7cd6101e04ac48ae6aa383572d2c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: