update runtime code

新增LoadAllAssetsAsync方法
pull/122/head
hevinci 2023-06-25 12:03:19 +08:00
parent 9dde15ac41
commit 8ccddce0f8
13 changed files with 545 additions and 20 deletions

View File

@ -260,6 +260,34 @@ namespace YooAsset
return provider.CreateHandle<SubAssetsOperationHandle>();
}
/// <summary>
/// 加载所有资源对象
/// </summary>
public AllAssetsOperationHandle LoadAllAssetsAsync(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<AllAssetsOperationHandle>();
}
string providerGUID = assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAllAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledAllAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerList.Add(provider);
_providerDic.Add(providerGUID, provider);
}
return provider.CreateHandle<AllAssetsOperationHandle>();
}
/// <summary>
/// 加载原生文件
/// </summary>
@ -377,10 +405,10 @@ namespace YooAsset
else
{
#if UNITY_WEBGL
if (bundleInfo.Bundle.IsRawFile)
loader = new RawBundleWebLoader(this, bundleInfo);
else
loader = new AssetBundleWebLoader(this, bundleInfo);
if (bundleInfo.Bundle.IsRawFile)
loader = new RawBundleWebLoader(this, bundleInfo);
else
loader = new AssetBundleWebLoader(this, bundleInfo);
#else
if (bundleInfo.Bundle.IsRawFile)
loader = new RawBundleFileLoader(this, bundleInfo);

View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
namespace YooAsset
{
public sealed class AllAssetsOperationHandle : OperationHandleBase, IDisposable
{
private System.Action<AllAssetsOperationHandle> _callback;
internal AllAssetsOperationHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<AllAssetsOperationHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AllAssetsOperationHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AllAssetsOperationHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 子资源对象集合
/// </summary>
public UnityEngine.Object[] AllAssetObjects
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AllAssetObjects;
}
}
}
}

View File

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

View File

@ -0,0 +1,112 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class BundledAllAssetsProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;
public BundledAllAssetsProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
}
public override void Update()
{
DebugBeginRecording();
if (IsDone)
return;
if (Status == EStatus.None)
{
Status = EStatus.CheckBundle;
}
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
DependBundleGroup.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete();
}
if (DependBundleGroup.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundleGroup.IsSucceed() == false)
{
Status = EStatus.Failed;
LastError = DependBundleGroup.GetLastError();
InvokeCompletion();
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
Status = EStatus.Failed;
LastError = OwnerBundle.LastError;
InvokeCompletion();
return;
}
Status = EStatus.Loading;
}
// 2. 加载资源对象
if (Status == EStatus.Loading)
{
if (IsWaitForAsyncComplete)
{
if (MainAssetInfo.AssetType == null)
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets();
else
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets(MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync();
else
_cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType);
}
Status = EStatus.Checking;
}
// 3. 检测加载结果
if (Status == EStatus.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AllAssetObjects = _cacheRequest.allAssets;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AllAssetObjects = _cacheRequest.allAssets;
}
}
Status = AllAssetObjects == null ? EStatus.Failed : EStatus.Succeed;
if (Status == EStatus.Failed)
{
if (MainAssetInfo.AssetType == null)
LastError = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
LastError = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
InvokeCompletion();
}
}
}
}

View File

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

View File

@ -0,0 +1,105 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class DatabaseAllAssetsProvider : ProviderBase
{
public DatabaseAllAssetsProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
}
public override void Update()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (Status == EStatus.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
Status = EStatus.Failed;
LastError = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(LastError);
InvokeCompletion();
return;
}
Status = EStatus.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
Status = EStatus.Failed;
LastError = OwnerBundle.LastError;
InvokeCompletion();
return;
}
Status = EStatus.Loading;
}
// 2. 加载资源对象
if (Status == EStatus.Loading)
{
if (MainAssetInfo.AssetType == null)
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssets)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadMainAssetAtPath(assetPath);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
else
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssets)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, MainAssetInfo.AssetType);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
Status = EStatus.Checking;
}
// 3. 检测加载结果
if (Status == EStatus.Checking)
{
Status = AllAssetObjects == null ? EStatus.Failed : EStatus.Succeed;
if (Status == EStatus.Failed)
{
if (MainAssetInfo.AssetType == null)
LastError = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null";
else
LastError = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(LastError);
}
InvokeCompletion();
}
#endif
}
}
}

View File

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

View File

@ -177,6 +177,8 @@ namespace YooAsset
handle = new SceneOperationHandle(this);
else if (typeof(T) == typeof(SubAssetsOperationHandle))
handle = new SubAssetsOperationHandle(this);
else if (typeof(T) == typeof(AllAssetsOperationHandle))
handle = new AllAssetsOperationHandle(this);
else if (typeof(T) == typeof(RawFileOperationHandle))
handle = new RawFileOperationHandle(this);
else

View File

@ -26,9 +26,9 @@ namespace YooAsset
public string RemoteFallbackURL { private set; get; }
/// <summary>
/// 编辑器资源路径
/// 注意:该字段只用于帮助编辑器下的模拟模式。
/// </summary>
public string EditorAssetPath { private set; get; }
public string[] IncludeAssets;
private BundleInfo()
@ -40,15 +40,6 @@ namespace YooAsset
LoadMode = loadMode;
RemoteMainURL = mainURL;
RemoteFallbackURL = fallbackURL;
EditorAssetPath = string.Empty;
}
public BundleInfo(PackageBundle bundle, ELoadMode loadMode, string editorAssetPath)
{
Bundle = bundle;
LoadMode = loadMode;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
EditorAssetPath = editorAssetPath;
}
public BundleInfo(PackageBundle bundle, ELoadMode loadMode)
{
@ -56,10 +47,8 @@ namespace YooAsset
LoadMode = loadMode;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
EditorAssetPath = string.Empty;
}
/// <summary>
/// 是否为JAR包内文件
/// </summary>

View File

@ -308,6 +308,25 @@ namespace YooAsset
}
}
/// <summary>
/// 获取资源包内的主资源列表
/// </summary>
public string[] GetBundleIncludeAssets(string assetPath)
{
List<string> assetList = new List<string>();
if (TryGetPackageAsset(assetPath, out PackageAsset result))
{
foreach (var packageAsset in AssetList)
{
if (packageAsset.BundleID == result.BundleID)
{
assetList.Add(packageAsset.AssetPath);
}
}
}
return assetList.ToArray();
}
#region 调试方法
[Conditional("DEBUG")]
private void DebugCheckLocation(string location)

View File

@ -33,7 +33,7 @@ namespace YooAsset
return _activeManifest;
}
}
public void FlushManifestVersionFile()
public void FlushManifestVersionFile()
{
}
@ -55,7 +55,7 @@ namespace YooAsset
OperationSystem.StartOperation(operation);
return operation;
}
ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout);
@ -85,7 +85,8 @@ namespace YooAsset
if (packageBundle == null)
throw new Exception("Should never get here !");
BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromEditor, assetInfo.AssetPath);
BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromEditor);
bundleInfo.IncludeAssets = _activeManifest.GetBundleIncludeAssets(assetInfo.AssetPath);
return bundleInfo;
}
BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo)

View File

@ -650,6 +650,95 @@ namespace YooAsset
}
#endregion
#region 资源加载
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public AllAssetsOperationHandle LoadAllAssetsSync(AssetInfo assetInfo)
{
DebugCheckInitialize();
return LoadAllAssetsInternal(assetInfo, true);
}
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public AllAssetsOperationHandle LoadAllAssetsSync<TObject>(string location) where TObject : UnityEngine.Object
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
return LoadAllAssetsInternal(assetInfo, true);
}
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public AllAssetsOperationHandle LoadAllAssetsSync(string location, System.Type type)
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
return LoadAllAssetsInternal(assetInfo, true);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public AllAssetsOperationHandle LoadAllAssetsAsync(AssetInfo assetInfo)
{
DebugCheckInitialize();
return LoadAllAssetsInternal(assetInfo, false);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public AllAssetsOperationHandle LoadAllAssetsAsync<TObject>(string location) where TObject : UnityEngine.Object
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
return LoadAllAssetsInternal(assetInfo, false);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public AllAssetsOperationHandle LoadAllAssetsAsync(string location, System.Type type)
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
return LoadAllAssetsInternal(assetInfo, false);
}
private AllAssetsOperationHandle LoadAllAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
{
#if UNITY_EDITOR
if (assetInfo.IsInvalid == false)
{
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
if (bundleInfo.Bundle.IsRawFile)
throw new Exception($"Cannot load raw file using {nameof(LoadAllAssetsAsync)} method !");
}
#endif
var handle = _assetSystemImpl.LoadAllAssetsAsync(assetInfo);
if (waitForAsyncComplete)
handle.WaitForAsyncComplete();
return handle;
}
#endregion
#region 资源下载
/// <summary>
/// 创建资源下载器,用于下载当前资源版本所有的资源包文件

View File

@ -284,6 +284,73 @@ namespace YooAsset
}
#endregion
#region 资源加载
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public static AllAssetsOperationHandle LoadAllAssetsSync(AssetInfo assetInfo)
{
DebugCheckDefaultPackageValid();
return _defaultPackage.LoadAllAssetsSync(assetInfo);
}
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public static AllAssetsOperationHandle LoadAllAssetsSync<TObject>(string location) where TObject : UnityEngine.Object
{
DebugCheckDefaultPackageValid();
return _defaultPackage.LoadAllAssetsSync<TObject>(location);
}
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public static AllAssetsOperationHandle LoadAllAssetsSync(string location, System.Type type)
{
DebugCheckDefaultPackageValid();
return _defaultPackage.LoadAllAssetsSync(location, type);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public static AllAssetsOperationHandle LoadAllAssetsAsync(AssetInfo assetInfo)
{
DebugCheckDefaultPackageValid();
return _defaultPackage.LoadAllAssetsAsync(assetInfo);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public static AllAssetsOperationHandle LoadAllAssetsAsync<TObject>(string location) where TObject : UnityEngine.Object
{
DebugCheckDefaultPackageValid();
return _defaultPackage.LoadAllAssetsAsync<TObject>(location);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public static AllAssetsOperationHandle LoadAllAssetsAsync(string location, System.Type type)
{
DebugCheckDefaultPackageValid();
return _defaultPackage.LoadAllAssetsAsync(location, type);
}
#endregion
#region 资源下载
/// <summary>
/// 创建资源下载器,用于下载当前资源版本所有的资源包文件