update resource manager

重构运行时核心代码
pull/418/head
何冠峰 2024-12-24 18:45:37 +08:00
parent 6254d00bb5
commit 4fc0d06908
56 changed files with 610 additions and 1715 deletions

View File

@ -90,23 +90,6 @@ namespace YooAsset
return fileSystemParams;
}
/// <summary>
/// 创建默认的内置文件系统参数(原生文件)
/// </summary>
/// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="verifyLevel">缓存文件的校验等级</param>
/// <param name="rootDirectory">内置文件的根路径</param>
public static FileSystemParameters CreateDefaultBuildinRawFileSystemParameters(IDecryptionServices decryptionServices = null, EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null)
{
string fileSystemClass = typeof(DefaultBuildinFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, verifyLevel);
fileSystemParams.AddParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, true);
fileSystemParams.AddParameter(FileSystemParametersDefine.RAW_FILE_BUILD_PIPELINE, true);
return fileSystemParams;
}
/// <summary>
/// 创建默认的缓存文件系统参数
/// </summary>
@ -124,25 +107,6 @@ namespace YooAsset
return fileSystemParams;
}
/// <summary>
/// 创建默认的缓存文件系统参数(原生文件)
/// </summary>
/// <param name="remoteServices">远端资源地址查询服务类</param>
/// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="verifyLevel">缓存文件的校验等级</param>
/// <param name="rootDirectory">文件系统的根目录</param>
public static FileSystemParameters CreateDefaultCacheRawFileSystemParameters(IRemoteServices remoteServices, IDecryptionServices decryptionServices = null, EFileVerifyLevel verifyLevel = EFileVerifyLevel.Middle, string rootDirectory = null)
{
string fileSystemClass = typeof(DefaultCacheFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, rootDirectory);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, verifyLevel);
fileSystemParams.AddParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, true);
fileSystemParams.AddParameter(FileSystemParametersDefine.RAW_FILE_BUILD_PIPELINE, true);
return fileSystemParams;
}
/// <summary>
/// 创建默认的WebServer文件系统参数
/// </summary>

View File

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

View File

@ -1,36 +0,0 @@

namespace YooAsset
{
internal class RawBundle
{
private readonly IFileSystem _fileSystem;
private readonly PackageBundle _packageBundle;
private readonly string _filePath;
internal RawBundle(IFileSystem fileSystem, PackageBundle packageBundle, string filePath)
{
_fileSystem = fileSystem;
_packageBundle = packageBundle;
_filePath = filePath;
}
public string GetFilePath()
{
return _filePath;
}
public byte[] ReadFileData()
{
if (_fileSystem != null)
return _fileSystem.ReadFileData(_packageBundle);
else
return FileUtility.ReadAllBytes(_filePath);
}
public string ReadFileText()
{
if (_fileSystem != null)
return _fileSystem.ReadFileText(_packageBundle);
else
return FileUtility.ReadAllText(_filePath);
}
}
}

View File

@ -1,15 +0,0 @@

namespace YooAsset
{
internal class VirtualBundle
{
private readonly IFileSystem _fileSystem;
private readonly PackageBundle _packageBundle;
internal VirtualBundle(IFileSystem fileSystem, PackageBundle packageBundle)
{
_fileSystem = fileSystem;
_packageBundle = packageBundle;
}
}
}

View File

@ -72,7 +72,7 @@ namespace YooAsset
{
if (IsValidWithWarning == false)
return null;
return Provider.RawBundleObject.ReadFileData();
return Provider.BundleResultObject.ReadBundleFileData();
}
/// <summary>
@ -82,7 +82,7 @@ namespace YooAsset
{
if (IsValidWithWarning == false)
return null;
return Provider.RawBundleObject.ReadFileText();
return Provider.BundleResultObject.ReadBundleFileText();
}
/// <summary>
@ -92,7 +92,7 @@ namespace YooAsset
{
if (IsValidWithWarning == false)
return string.Empty;
return Provider.RawBundleObject.GetFilePath();
return Provider.BundleResultObject.GetBundleFilePath();
}
}
}

View File

@ -100,14 +100,9 @@ namespace YooAsset
if (IsValidWithWarning == false)
return false;
if (Provider is DatabaseSceneProvider)
if (Provider is SceneProvider)
{
var provider = Provider as DatabaseSceneProvider;
provider.UnSuspendLoad();
}
else if (Provider is BundledSceneProvider)
{
var provider = Provider as BundledSceneProvider;
var provider = Provider as SceneProvider;
provider.UnSuspendLoad();
}
else
@ -125,14 +120,9 @@ namespace YooAsset
if (IsValidWithWarning == false)
return false;
if (Provider is DatabaseSceneProvider)
if (Provider is SceneProvider)
{
var temp = Provider as DatabaseSceneProvider;
return temp.SceneMode == LoadSceneMode.Single;
}
else if (Provider is BundledSceneProvider)
{
var temp = Provider as BundledSceneProvider;
var temp = Provider as SceneProvider;
return temp.SceneMode == LoadSceneMode.Single;
}
else

View File

@ -67,13 +67,13 @@ namespace YooAsset
/// <summary>
/// 子资源对象集合
/// </summary>
public IReadOnlyList<UnityEngine.Object> AllAssetObjects
public IReadOnlyList<UnityEngine.Object> SubAssetObjects
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AllAssetObjects;
return Provider.SubAssetObjects;
}
}
@ -87,7 +87,7 @@ namespace YooAsset
if (IsValidWithWarning == false)
return null;
foreach (var assetObject in Provider.AllAssetObjects)
foreach (var assetObject in Provider.SubAssetObjects)
{
if (assetObject.name == assetName && assetObject is TObject)
return assetObject as TObject;
@ -106,8 +106,8 @@ namespace YooAsset
if (IsValidWithWarning == false)
return null;
List<TObject> ret = new List<TObject>(Provider.AllAssetObjects.Length);
foreach (var assetObject in Provider.AllAssetObjects)
List<TObject> ret = new List<TObject>(Provider.SubAssetObjects.Length);
foreach (var assetObject in Provider.SubAssetObjects)
{
var retObject = assetObject as TObject;
if (retObject != null)

View File

@ -22,7 +22,7 @@ namespace YooAsset
/// <summary>
/// 资源包文件信息
/// </summary>
public BundleInfo BundleFileInfo { private set; get; }
public BundleInfo LoadBundleInfo { private set; get; }
/// <summary>
/// 是否已经销毁
@ -47,13 +47,13 @@ namespace YooAsset
/// <summary>
/// 加载结果
/// </summary>
public object Result { set; get; }
public BundleResult Result { set; get; }
internal LoadBundleFileOperation(ResourceManager resourceManager, BundleInfo bundleInfo)
{
_resourceManager = resourceManager;
BundleFileInfo = bundleInfo;
LoadBundleInfo = bundleInfo;
}
internal override void InternalOnStart()
{
@ -67,7 +67,7 @@ namespace YooAsset
if (_steps == ESteps.LoadFile)
{
if (_loadBundleOp == null)
_loadBundleOp = BundleFileInfo.LoadBundleFile();
_loadBundleOp = LoadBundleInfo.LoadBundleFile();
if (IsWaitForAsyncComplete)
_loadBundleOp.WaitForAsyncComplete();
@ -83,7 +83,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The bundle loader result is null ! {BundleFileInfo.Bundle.BundleName}";
Error = $"The bundle loader result is null ! {LoadBundleInfo.Bundle.BundleName}";
}
else
{
@ -137,11 +137,12 @@ namespace YooAsset
// Check fatal
if (RefCount > 0)
throw new Exception($"Bundle file loader ref is not zero : {BundleFileInfo.Bundle.BundleName}");
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 : {BundleFileInfo.Bundle.BundleName}");
throw new Exception($"Bundle file loader is not done : {LoadBundleInfo.Bundle.BundleName}");
BundleFileInfo.UnloadBundleFile(Result);
if (Result != null)
Result.UnloadBundleFile();
}
/// <summary>

View File

@ -1,129 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace YooAsset
{
internal class LoadDependBundleFileOperation : AsyncOperationBase
{
private enum ESteps
{
None,
CheckDepend,
CheckResult,
Done,
}
/// <summary>
/// 依赖的资源包加载器列表
/// </summary>
internal readonly List<LoadBundleFileOperation> Depends;
private ESteps _steps = ESteps.None;
internal LoadDependBundleFileOperation(List<LoadBundleFileOperation> dpends)
{
Depends = dpends;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckDepend;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckDepend)
{
if (IsWaitForAsyncComplete)
{
foreach (var loader in Depends)
{
loader.WaitForAsyncComplete();
}
}
foreach (var loader in Depends)
{
if (loader.IsDone == false)
return;
}
_steps = ESteps.CheckResult;
}
if (_steps == ESteps.CheckResult)
{
LoadBundleFileOperation failedLoader = null;
foreach (var loader in Depends)
{
if (loader.Status != EOperationStatus.Succeed)
{
failedLoader = loader;
break;
}
}
if (failedLoader == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = failedLoader.Error;
}
}
}
internal override void InternalWaitForAsyncComplete()
{
while (true)
{
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
break;
}
}
}
/// <summary>
/// 增加引用计数
/// </summary>
public void Reference()
{
foreach (var loader in Depends)
{
loader.Reference();
}
}
/// <summary>
/// 减少引用计数
/// </summary>
public void Release()
{
foreach (var loader in Depends)
{
loader.Release();
}
}
/// <summary>
/// 获取资源包的调试信息列表
/// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
foreach (var loader in Depends)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = loader.BundleFileInfo.Bundle.BundleName;
bundleInfo.RefCount = loader.RefCount;
bundleInfo.Status = loader.Status;
output.Add(bundleInfo);
}
}
}
}

View File

@ -74,7 +74,7 @@ namespace YooAsset
}
#if UNITY_2023_3_OR_NEWER
//TODO
//TODO : 官方BUG
// BUG环境Windows平台Unity2022.3.41f1版本,编辑器模式。
// BUG描述异步实例化Prefab预制体有概率丢失Mono脚本里序列化的数组里某个成员
//_steps = ESteps.CloneAsync;

View File

@ -32,14 +32,9 @@ namespace YooAsset
_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

View File

@ -52,7 +52,7 @@ namespace YooAsset
// 销毁文件加载器
foreach (var loader in removeList)
{
string bundleName = loader.BundleFileInfo.Bundle.BundleName;
string bundleName = loader.LoadBundleInfo.Bundle.BundleName;
loader.DestroyLoader();
_resManager._loaderDic.Remove(bundleName);
}

View File

@ -0,0 +1,36 @@

namespace YooAsset
{
internal sealed class AllAssetsProvider : ProviderOperation
{
private FSLoadAllAssetsOperation _loadAllAssetsOp;
public AllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
protected override void ProcessBundleResult()
{
if (_loadAllAssetsOp == null)
{
_loadAllAssetsOp = BundleResultObject.LoadAllAssetsAsync(MainAssetInfo);
}
if (IsWaitForAsyncComplete)
_loadAllAssetsOp.WaitForAsyncComplete();
Progress = _loadAllAssetsOp.Progress;
if (_loadAllAssetsOp.IsDone == false)
return;
if (_loadAllAssetsOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(_loadAllAssetsOp.Error, EOperationStatus.Failed);
}
else
{
AllAssetObjects = _loadAllAssetsOp.Result;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9b0e966838827284a9266a9f2237a460
guid: 33f2d909fd8d9ab4eaedcded2519d1d8
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,36 @@

namespace YooAsset
{
internal sealed class AssetProvider : ProviderOperation
{
private FSLoadAssetOperation _loadAssetOp;
public AssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
protected override void ProcessBundleResult()
{
if (_loadAssetOp == null)
{
_loadAssetOp = BundleResultObject.LoadAssetAsync(MainAssetInfo);
}
if (IsWaitForAsyncComplete)
_loadAssetOp.WaitForAsyncComplete();
Progress = _loadAssetOp.Progress;
if (_loadAssetOp.IsDone == false)
return;
if (_loadAssetOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(_loadAssetOp.Error, EOperationStatus.Failed);
}
else
{
AssetObject = _loadAssetOp.Result;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 822bb85f05144d842977dda341174db2
guid: e6adffc18dc473141ad72e0f5da5dada
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -1,123 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class BundledAllAssetsProvider : ProviderOperation
{
private AssetBundle _assetBundle;
private AssetBundleRequest _cacheRequest;
public BundledAllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadDependBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadDependBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadDependBundleFileOp.Error, EOperationStatus.Failed);
return;
}
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
if (LoadBundleFileOp.Result == null)
{
ProcessFatalEvent();
return;
}
if (LoadBundleFileOp.Result is AssetBundle == false)
{
string error = "Try load raw file using load assetbundle method !";
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_assetBundle = LoadBundleFileOp.Result as AssetBundle;
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete)
{
if (MainAssetInfo.AssetType == null)
AllAssetObjects = _assetBundle.LoadAllAssets();
else
AllAssetObjects = _assetBundle.LoadAllAssets(MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = _assetBundle.LoadAllAssetsAsync();
else
_cacheRequest = _assetBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.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;
}
}
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {LoadBundleFileOp.BundleFileInfo.Bundle.BundleName}";
else
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {LoadBundleFileOp.BundleFileInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
}

View File

@ -1,123 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class BundledAssetProvider : ProviderOperation
{
private AssetBundle _assetBundle;
private AssetBundleRequest _cacheRequest;
public BundledAssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadDependBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadDependBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadDependBundleFileOp.Error, EOperationStatus.Failed);
return;
}
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
if (LoadBundleFileOp.Result == null)
{
ProcessFatalEvent();
return;
}
if (LoadBundleFileOp.Result is AssetBundle == false)
{
string error = "Try load raw file using load assetbundle method !";
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_assetBundle = LoadBundleFileOp.Result as AssetBundle;
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete)
{
if (MainAssetInfo.AssetType == null)
AssetObject = _assetBundle.LoadAsset(MainAssetInfo.AssetPath);
else
AssetObject = _assetBundle.LoadAsset(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = _assetBundle.LoadAssetAsync(MainAssetInfo.AssetPath);
else
_cacheRequest = _assetBundle.LoadAssetAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AssetObject = _cacheRequest.asset;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AssetObject = _cacheRequest.asset;
}
}
if (AssetObject == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {LoadBundleFileOp.BundleFileInfo.Bundle.BundleName}";
else
error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {LoadBundleFileOp.BundleFileInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
}

View File

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

View File

@ -1,53 +0,0 @@

namespace YooAsset
{
internal class BundledRawFileProvider : ProviderOperation
{
public BundledRawFileProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
if (LoadBundleFileOp.Result is RawBundle == false)
{
string error = "Try load AssetBundle file using load raw file method !";
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Checking;
}
// 2. 检测加载结果
if (_steps == ESteps.Checking)
{
RawBundleObject = LoadBundleFileOp.Result as RawBundle;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}

View File

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

View File

@ -1,148 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace YooAsset
{
internal sealed class BundledSceneProvider : ProviderOperation
{
public readonly LoadSceneParameters LoadSceneParams;
private AsyncOperation _asyncOperation;
private bool _suspendLoadMode;
/// <summary>
/// 场景加载模式
/// </summary>
public LoadSceneMode SceneMode
{
get
{
return LoadSceneParams.loadSceneMode;
}
}
public BundledSceneProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad) : base(manager, providerGUID, assetInfo)
{
LoadSceneParams = loadSceneParams;
SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
_suspendLoadMode = suspendLoad;
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadDependBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadDependBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadDependBundleFileOp.Error, EOperationStatus.Failed);
return;
}
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
// 2. 加载场景
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete)
{
// 注意:场景同步加载方法不会立即加载场景,而是在下一帧加载。
SceneObject = SceneManager.LoadScene(MainAssetInfo.AssetPath, LoadSceneParams);
_steps = ESteps.Checking;
}
else
{
// 注意如果场景不存在异步加载方法返回NULL
// 注意:即使是异步加载也要在当帧获取到场景对象
_asyncOperation = SceneManager.LoadSceneAsync(MainAssetInfo.AssetPath, LoadSceneParams);
if (_asyncOperation != null)
{
_asyncOperation.allowSceneActivation = !_suspendLoadMode;
_asyncOperation.priority = 100;
SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
_steps = ESteps.Checking;
}
else
{
string error = $"Failed to load scene : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_asyncOperation != null)
{
if (IsWaitForAsyncComplete)
{
// 场景加载无法强制异步转同步
YooLogger.Error("The scene is loading asyn !");
}
else
{
// 注意:在业务层中途可以取消挂起
if (_asyncOperation.allowSceneActivation == false)
{
if (_suspendLoadMode == false)
_asyncOperation.allowSceneActivation = true;
}
Progress = _asyncOperation.progress;
if (_asyncOperation.isDone == false)
return;
}
}
if (SceneObject.IsValid())
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
else
{
string error = $"The loaded scene is invalid : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public void UnSuspendLoad()
{
if (IsDone == false)
{
_suspendLoadMode = false;
}
}
}
}

View File

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

View File

@ -1,123 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class BundledSubAssetsProvider : ProviderOperation
{
private AssetBundle _assetBundle;
private AssetBundleRequest _cacheRequest;
public BundledSubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadDependBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadDependBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadDependBundleFileOp.Error, EOperationStatus.Failed);
return;
}
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
if (LoadBundleFileOp.Result == null)
{
ProcessFatalEvent();
return;
}
if (LoadBundleFileOp.Result is AssetBundle == false)
{
string error = "Try load raw file using load assetbundle method !";
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_assetBundle = LoadBundleFileOp.Result as AssetBundle;
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete)
{
if (MainAssetInfo.AssetType == null)
AllAssetObjects = _assetBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath);
else
AllAssetObjects = _assetBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = _assetBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath);
else
_cacheRequest = _assetBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.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;
}
}
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {LoadBundleFileOp.BundleFileInfo.Bundle.BundleName}";
else
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {LoadBundleFileOp.BundleFileInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
}

View File

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

View File

@ -6,20 +6,13 @@ namespace YooAsset
public CompletedProvider(ResourceManager manager, AssetInfo assetInfo) : base(manager, string.Empty, assetInfo)
{
}
internal override void InternalOnStart()
{
}
internal override void InternalOnUpdate()
protected override void ProcessBundleResult()
{
}
public void SetCompleted(string error)
public void SetCompletedWithError(string error)
{
if (_steps == ESteps.None)
{
InvokeCompletion(error, EOperationStatus.Failed);
}
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}

View File

@ -1,105 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class DatabaseAllAssetsProvider : ProviderOperation
{
public DatabaseAllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in LoadBundleFileOp.BundleFileInfo.IncludeAssetsInEditor)
{
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 LoadBundleFileOp.BundleFileInfo.IncludeAssetsInEditor)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, MainAssetInfo.AssetType);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
#endif
}
}
}

View File

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

View File

@ -1,87 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class DatabaseAssetProvider : ProviderOperation
{
public DatabaseAssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
AssetObject = UnityEditor.AssetDatabase.LoadMainAssetAtPath(MainAssetInfo.AssetPath);
else
AssetObject = UnityEditor.AssetDatabase.LoadAssetAtPath(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AssetObject == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
#endif
}
}
}

View File

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

View File

@ -1,62 +0,0 @@

namespace YooAsset
{
internal class DatabaseRawFileProvider : ProviderOperation
{
public DatabaseRawFileProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Checking;
}
// 2. 检测加载结果
if (_steps == ESteps.Checking)
{
RawBundleObject = new RawBundle(null, null, MainAssetInfo.AssetPath);
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
#endif
}
}
}

View File

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

View File

@ -1,139 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace YooAsset
{
internal sealed class DatabaseSceneProvider : ProviderOperation
{
public readonly LoadSceneParameters LoadSceneParams;
private AsyncOperation _asyncOperation;
private bool _suspendLoadMode;
/// <summary>
/// 场景加载模式
/// </summary>
public LoadSceneMode SceneMode
{
get
{
return LoadSceneParams.loadSceneMode;
}
}
public DatabaseSceneProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad) : base(manager, providerGUID, assetInfo)
{
LoadSceneParams = loadSceneParams;
SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
_suspendLoadMode = suspendLoad;
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete)
{
SceneObject = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneInPlayMode(MainAssetInfo.AssetPath, LoadSceneParams);
_steps = ESteps.Checking;
}
else
{
_asyncOperation = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(MainAssetInfo.AssetPath, LoadSceneParams);
if (_asyncOperation != null)
{
_asyncOperation.allowSceneActivation = !_suspendLoadMode;
_asyncOperation.priority = 100;
SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
_steps = ESteps.Checking;
}
else
{
string error = $"Failed to load scene : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_asyncOperation != null)
{
if (IsWaitForAsyncComplete)
{
// 场景加载无法强制异步转同步
YooLogger.Error("The scene is loading asyn !");
}
else
{
// 注意:在业务层中途可以取消挂起
if (_asyncOperation.allowSceneActivation == false)
{
if (_suspendLoadMode == false)
_asyncOperation.allowSceneActivation = true;
}
Progress = _asyncOperation.progress;
if (_asyncOperation.isDone == false)
return;
}
}
if (SceneObject.IsValid())
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
else
{
string error = $"The loaded scene is invalid : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
#endif
}
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public void UnSuspendLoad()
{
if (IsDone == false)
{
_suspendLoadMode = false;
}
}
}
}

View File

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

View File

@ -1,98 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class DatabaseSubAssetsProvider : ProviderOperation
{
public DatabaseSubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (LoadBundleFileOp.IsDone == false)
return;
if (LoadBundleFileOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(LoadBundleFileOp.Error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
{
AllAssetObjects = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(MainAssetInfo.AssetPath);
}
else
{
UnityEngine.Object[] findAssets = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(MainAssetInfo.AssetPath);
List<UnityEngine.Object> result = new List<Object>(findAssets.Length);
foreach (var findAsset in findAssets)
{
if (MainAssetInfo.AssetType.IsAssignableFrom(findAsset.GetType()))
result.Add(findAsset);
}
AllAssetObjects = result.ToArray();
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
#endif
}
}
}

View File

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

View File

@ -10,9 +10,8 @@ namespace YooAsset
protected enum ESteps
{
None = 0,
CheckBundle,
Loading,
Checking,
LoadBundleFile,
ProcessBundleResult,
Done,
}
@ -41,15 +40,20 @@ namespace YooAsset
/// </summary>
public UnityEngine.Object[] AllAssetObjects { protected set; get; }
/// <summary>
/// 获取的资源对象集合
/// </summary>
public UnityEngine.Object[] SubAssetObjects { protected set; get; }
/// <summary>
/// 获取的场景对象
/// </summary>
public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; }
/// <summary>
/// 获取的原生对象
/// 获取的资源包对象
/// </summary>
public RawBundle RawBundleObject { protected set; get; }
public BundleResult BundleResultObject { protected set; get; }
/// <summary>
/// 加载的场景名称
@ -67,9 +71,9 @@ namespace YooAsset
public bool IsDestroyed { private set; get; } = false;
protected ESteps _steps = ESteps.None;
protected LoadBundleFileOperation LoadBundleFileOp { private set; get; }
protected LoadDependBundleFileOperation LoadDependBundleFileOp { private set; get; }
private ESteps _steps = ESteps.None;
private readonly LoadBundleFileOperation _mainBundleLoader;
private readonly List<LoadBundleFileOperation> _bundleLoaders = new List<LoadBundleFileOperation>();
private readonly List<HandleBase> _handles = new List<HandleBase>();
@ -81,25 +85,75 @@ namespace YooAsset
if (string.IsNullOrEmpty(providerGUID) == false)
{
LoadBundleFileOp = manager.CreateMainBundleFileLoader(assetInfo);
LoadBundleFileOp.Reference();
LoadBundleFileOp.AddProvider(this);
// 主资源包加载器
_mainBundleLoader = manager.CreateMainBundleFileLoader(assetInfo);
_mainBundleLoader.AddProvider(this);
_bundleLoaders.Add(_mainBundleLoader);
LoadDependBundleFileOp = manager.CreateDependFileLoaders(assetInfo);
LoadDependBundleFileOp.Reference();
// 依赖资源包加载器集合
var dependLoaders = manager.CreateDependBundleFileLoaders(assetInfo);
if(dependLoaders.Count > 0)
_bundleLoaders.AddRange(dependLoaders);
// 增加引用计数
foreach (var bundleLoader in _bundleLoaders)
{
bundleLoader.Reference();
}
}
}
internal override void InternalOnStart()
{
DebugBeginRecording();
_steps = ESteps.LoadBundleFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBundleFile)
{
if (IsWaitForAsyncComplete)
{
foreach (var bundleLoader in _bundleLoaders)
{
bundleLoader.WaitForAsyncComplete();
}
}
foreach (var bundleLoader in _bundleLoaders)
{
if (bundleLoader.IsDone == false)
return;
if (bundleLoader.Status != EOperationStatus.Succeed)
{
InvokeCompletion(bundleLoader.Error, EOperationStatus.Failed);
return;
}
}
BundleResultObject = _mainBundleLoader.Result;
if (BundleResultObject == null)
{
string error = $"Loaded bundle result is null !";
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.ProcessBundleResult;
}
if (_steps == ESteps.ProcessBundleResult)
{
ProcessBundleResult();
}
}
internal override void InternalWaitForAsyncComplete()
{
while (true)
{
if (LoadDependBundleFileOp != null)
LoadDependBundleFileOp.WaitForAsyncComplete();
if (LoadBundleFileOp != null)
LoadBundleFileOp.WaitForAsyncComplete();
if (ExecuteWhileDone())
{
_steps = ESteps.Done;
@ -107,6 +161,7 @@ namespace YooAsset
}
}
}
protected abstract void ProcessBundleResult();
/// <summary>
/// 销毁资源提供者
@ -122,16 +177,10 @@ namespace YooAsset
Status = EOperationStatus.Failed;
}
// 释放资源包加载器
if (LoadBundleFileOp != null)
// 减少引用计数
foreach (var bundleLoader in _bundleLoaders)
{
LoadBundleFileOp.Release();
LoadBundleFileOp = null;
}
if (LoadDependBundleFileOp != null)
{
LoadDependBundleFileOp.Release();
LoadDependBundleFileOp = null;
bundleLoader.Release();
}
}
@ -141,7 +190,7 @@ namespace YooAsset
public bool CanDestroyProvider()
{
// 注意:在进行资源加载过程时不可以销毁
if (_steps == ESteps.Loading || _steps == ESteps.Checking)
if (_steps == ESteps.ProcessBundleResult)
return false;
return RefCount <= 0;
@ -200,19 +249,6 @@ namespace YooAsset
}
}
/// <summary>
/// 处理致命问题
/// </summary>
protected void ProcessFatalEvent()
{
if (LoadBundleFileOp.IsDestroyed)
throw new System.Exception("Should never get here !");
string error = $"The bundle {LoadBundleFileOp.BundleFileInfo.Bundle.BundleName} has been destroyed by unity bugs !";
YooLogger.Error(error);
InvokeCompletion(Error, EOperationStatus.Failed);
}
/// <summary>
/// 结束流程
/// </summary>
@ -242,12 +278,10 @@ namespace YooAsset
public DownloadStatus GetDownloadStatus()
{
DownloadStatus status = new DownloadStatus();
status.TotalBytes = LoadBundleFileOp.BundleFileInfo.Bundle.FileSize;
status.DownloadedBytes = LoadBundleFileOp.DownloadedBytes;
foreach (var dependBundle in LoadDependBundleFileOp.Depends)
foreach (var bundleLoader in _bundleLoaders)
{
status.TotalBytes += dependBundle.BundleFileInfo.Bundle.FileSize;
status.DownloadedBytes += dependBundle.DownloadedBytes;
status.TotalBytes += bundleLoader.LoadBundleInfo.Bundle.FileSize;
status.DownloadedBytes += bundleLoader.DownloadedBytes;
}
if (status.TotalBytes == 0)
@ -315,13 +349,14 @@ namespace YooAsset
/// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = LoadBundleFileOp.BundleFileInfo.Bundle.BundleName;
bundleInfo.RefCount = LoadBundleFileOp.RefCount;
bundleInfo.Status = LoadBundleFileOp.Status;
output.Add(bundleInfo);
LoadDependBundleFileOp.GetBundleDebugInfos(output);
foreach (var bundleLoader in _bundleLoaders)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = bundleLoader.LoadBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = bundleLoader.RefCount;
bundleInfo.Status = bundleLoader.Status;
output.Add(bundleInfo);
}
}
#endregion
}

View File

@ -0,0 +1,14 @@

namespace YooAsset
{
internal class RawFileProvider : ProviderOperation
{
public RawFileProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
protected override void ProcessBundleResult()
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c6e71c986d2a8c74d981deeed7b5a8ef
guid: 49b6e666518da98479966a5cf0504d59
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,69 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace YooAsset
{
internal sealed class SceneProvider : ProviderOperation
{
private readonly LoadSceneParameters _loadParams;
private bool _suspendLoad;
private FSLoadSceneOperation _loadSceneOp;
/// <summary>
/// 场景加载模式
/// </summary>
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;
_suspendLoad = suspendLoad;
SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
}
protected override void ProcessBundleResult()
{
if (_loadSceneOp == null)
{
_loadSceneOp = BundleResultObject.LoadSceneOperation(MainAssetInfo, _loadParams, _suspendLoad);
}
if (IsWaitForAsyncComplete)
_loadSceneOp.WaitForAsyncComplete();
// 注意:场景加载中途可以取消挂起
if (_suspendLoad == false)
_loadSceneOp.UnSuspendLoad();
Progress = _loadSceneOp.Progress;
if (_loadSceneOp.IsDone == false)
return;
if (_loadSceneOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(_loadSceneOp.Error, EOperationStatus.Failed);
}
else
{
SceneObject = _loadSceneOp.Result;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public void UnSuspendLoad()
{
_suspendLoad = false;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 3834f832061fdd74fbfb1eba381b1b3e
guid: 8586015105ad65f438e2f2e9c64c3df1
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,36 @@

namespace YooAsset
{
internal sealed class SubAssetsProvider : ProviderOperation
{
private FSLoadSubAssetsOperation _loadSubAssetsOp;
public SubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
protected override void ProcessBundleResult()
{
if (_loadSubAssetsOp == null)
{
_loadSubAssetsOp = BundleResultObject.LoadSubAssetsAsync(MainAssetInfo);
}
if (IsWaitForAsyncComplete)
_loadSubAssetsOp.WaitForAsyncComplete();
Progress = _loadSubAssetsOp.Progress;
if (_loadSubAssetsOp.IsDone == false)
return;
if (_loadSubAssetsOp.Status != EOperationStatus.Succeed)
{
InvokeCompletion(_loadSubAssetsOp.Error, EOperationStatus.Failed);
}
else
{
SubAssetObjects = _loadSubAssetsOp.Result;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}

View File

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

View File

@ -15,8 +15,6 @@ namespace YooAsset
internal readonly Dictionary<string, ProviderOperation> _providerDic = new Dictionary<string, ProviderOperation>(5000);
internal readonly Dictionary<string, LoadBundleFileOperation> _loaderDic = new Dictionary<string, LoadBundleFileOperation>(5000);
private bool _simulationOnEditor;
private IBundleQuery _bundleQuery;
/// <summary>
@ -35,7 +33,6 @@ namespace YooAsset
/// </summary>
public void Initialize(InitializeParameters initializeParameters, IBundleQuery bundleServices)
{
_simulationOnEditor = initializeParameters is EditorSimulateModeParameters;
_bundleQuery = bundleServices;
}
@ -52,13 +49,13 @@ namespace YooAsset
// 卸载主资源包加载器
string mainBundleName = _bundleQuery.GetMainBundleName(assetInfo);
var mainLoader = TryGetFileLoader(mainBundleName);
var mainLoader = TryGetBundleFileLoader(mainBundleName);
if (mainLoader != null)
{
mainLoader.TryDestroyProviders();
if (mainLoader.CanDestroyLoader())
{
string bundleName = mainLoader.BundleFileInfo.Bundle.BundleName;
string bundleName = mainLoader.LoadBundleInfo.Bundle.BundleName;
mainLoader.DestroyLoader();
_loaderDic.Remove(bundleName);
}
@ -68,12 +65,12 @@ namespace YooAsset
string[] dependBundleNames = _bundleQuery.GetDependBundleNames(assetInfo);
foreach (var dependBundleName in dependBundleNames)
{
var dependLoader = TryGetFileLoader(dependBundleName);
var dependLoader = TryGetBundleFileLoader(dependBundleName);
if (dependLoader != null)
{
if (dependLoader.CanDestroyLoader())
{
string bundleName = dependLoader.BundleFileInfo.Bundle.BundleName;
string bundleName = dependLoader.LoadBundleInfo.Bundle.BundleName;
dependLoader.DestroyLoader();
_loaderDic.Remove(bundleName);
}
@ -92,7 +89,7 @@ namespace YooAsset
{
YooLogger.Error($"Failed to load scene ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
completedProvider.SetCompletedWithError(assetInfo.Error);
return completedProvider.CreateHandle<SceneHandle>();
}
@ -106,10 +103,7 @@ namespace YooAsset
string providerGUID = $"{assetInfo.GUID}-{++_sceneCreateCount}";
ProviderOperation provider;
{
if (_simulationOnEditor)
provider = new DatabaseSceneProvider(this, providerGUID, assetInfo, loadSceneParams, suspendLoad);
else
provider = new BundledSceneProvider(this, providerGUID, assetInfo, loadSceneParams, suspendLoad);
provider = new SceneProvider(this, providerGUID, assetInfo, loadSceneParams, suspendLoad);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
@ -131,18 +125,15 @@ namespace YooAsset
{
YooLogger.Error($"Failed to load asset ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
completedProvider.SetCompletedWithError(assetInfo.Error);
return completedProvider.CreateHandle<AssetHandle>();
}
string providerGUID = nameof(LoadAssetAsync) + assetInfo.GUID;
ProviderOperation provider = TryGetProvider(providerGUID);
ProviderOperation provider = TryGetAssetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAssetProvider(this, providerGUID, assetInfo);
else
provider = new BundledAssetProvider(this, providerGUID, assetInfo);
provider = new AssetProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
@ -161,18 +152,15 @@ namespace YooAsset
{
YooLogger.Error($"Failed to load sub assets ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
completedProvider.SetCompletedWithError(assetInfo.Error);
return completedProvider.CreateHandle<SubAssetsHandle>();
}
string providerGUID = nameof(LoadSubAssetsAsync) + assetInfo.GUID;
ProviderOperation provider = TryGetProvider(providerGUID);
ProviderOperation provider = TryGetAssetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseSubAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledSubAssetsProvider(this, providerGUID, assetInfo);
provider = new SubAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
@ -191,18 +179,15 @@ namespace YooAsset
{
YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
completedProvider.SetCompletedWithError(assetInfo.Error);
return completedProvider.CreateHandle<AllAssetsHandle>();
}
string providerGUID = nameof(LoadAllAssetsAsync) + assetInfo.GUID;
ProviderOperation provider = TryGetProvider(providerGUID);
ProviderOperation provider = TryGetAssetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAllAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledAllAssetsProvider(this, providerGUID, assetInfo);
provider = new AllAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
@ -221,18 +206,15 @@ namespace YooAsset
{
YooLogger.Error($"Failed to load raw file ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
completedProvider.SetCompletedWithError(assetInfo.Error);
return completedProvider.CreateHandle<RawFileHandle>();
}
string providerGUID = nameof(LoadRawFileAsync) + assetInfo.GUID;
ProviderOperation provider = TryGetProvider(providerGUID);
ProviderOperation provider = TryGetAssetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseRawFileProvider(this, providerGUID, assetInfo);
else
provider = new BundledRawFileProvider(this, providerGUID, assetInfo);
provider = new RawFileProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
@ -295,20 +277,18 @@ namespace YooAsset
internal LoadBundleFileOperation CreateMainBundleFileLoader(AssetInfo assetInfo)
{
BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo);
return CreateFileLoaderInternal(bundleInfo);
return CreateBundleFileLoaderInternal(bundleInfo);
}
internal LoadDependBundleFileOperation CreateDependFileLoaders(AssetInfo assetInfo)
internal List<LoadBundleFileOperation> CreateDependBundleFileLoaders(AssetInfo assetInfo)
{
BundleInfo[] bundleInfos = _bundleQuery.GetDependBundleInfos(assetInfo);
List<LoadBundleFileOperation> depends = new List<LoadBundleFileOperation>(bundleInfos.Length);
List<LoadBundleFileOperation> result = new List<LoadBundleFileOperation>(bundleInfos.Length);
foreach (var bundleInfo in bundleInfos)
{
LoadBundleFileOperation dependLoader = CreateFileLoaderInternal(bundleInfo);
depends.Add(dependLoader);
var bundleLoader = CreateBundleFileLoaderInternal(bundleInfo);
result.Add(bundleLoader);
}
var operation = new LoadDependBundleFileOperation(depends);
OperationSystem.StartOperation(PackageName, operation);
return operation;
return result;
}
internal void RemoveBundleProviders(List<ProviderOperation> removeList)
{
@ -322,11 +302,11 @@ namespace YooAsset
return _loaderDic.Count > 0;
}
private LoadBundleFileOperation CreateFileLoaderInternal(BundleInfo bundleInfo)
private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
{
// 如果加载器已经存在
string bundleName = bundleInfo.Bundle.BundleName;
LoadBundleFileOperation loaderOperation = TryGetFileLoader(bundleName);
LoadBundleFileOperation loaderOperation = TryGetBundleFileLoader(bundleName);
if (loaderOperation != null)
return loaderOperation;
@ -336,14 +316,14 @@ namespace YooAsset
_loaderDic.Add(bundleName, loaderOperation);
return loaderOperation;
}
private LoadBundleFileOperation TryGetFileLoader(string bundleName)
private LoadBundleFileOperation TryGetBundleFileLoader(string bundleName)
{
if (_loaderDic.TryGetValue(bundleName, out LoadBundleFileOperation value))
return value;
else
return null;
}
private ProviderOperation TryGetProvider(string providerGUID)
private ProviderOperation TryGetAssetProvider(string providerGUID)
{
if (_providerDic.TryGetValue(providerGUID, out ProviderOperation value))
return value;

View File

@ -3,19 +3,14 @@ namespace YooAsset
{
internal class BundleInfo
{
private readonly string _importFilePath;
private readonly IFileSystem _fileSystem;
private readonly string _importFilePath;
/// <summary>
/// 资源包对象
/// </summary>
public readonly PackageBundle Bundle;
/// <summary>
/// 注意:该字段只用于帮助编辑器下的模拟模式。
/// </summary>
public string[] IncludeAssetsInEditor;
public BundleInfo(IFileSystem fileSystem, PackageBundle bundle)
{
@ -31,21 +26,13 @@ namespace YooAsset
}
/// <summary>
/// 加载资源文件
/// 加载资源
/// </summary>
public FSLoadBundleOperation LoadBundleFile()
{
return _fileSystem.LoadBundleFile(Bundle);
}
/// <summary>
/// 卸载资源文件
/// </summary>
public void UnloadBundleFile(object result)
{
_fileSystem.UnloadBundleFile(Bundle, result);
}
/// <summary>
/// 创建下载器
/// </summary>

View File

@ -0,0 +1,26 @@

namespace YooAsset
{
internal enum EBuildBundleType
{
/// <summary>
/// 未知类型
/// </summary>
Unknown = 0,
/// <summary>
/// 虚拟资源包
/// </summary>
VirtualBundle = 1,
/// <summary>
/// AssetBundle
/// </summary>
AssetBundle = 2,
/// <summary>
/// 原生文件
/// </summary>
RawBundle = 3,
}
}

View File

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

View File

@ -39,6 +39,7 @@ namespace YooAsset
buffer.WriteBool(manifest.LocationToLower);
buffer.WriteBool(manifest.IncludeAssetGUID);
buffer.WriteInt32(manifest.OutputNameStyle);
buffer.WriteInt32(manifest.BuildBundleType);
buffer.WriteUTF8(manifest.BuildPipeline);
buffer.WriteUTF8(manifest.PackageName);
buffer.WriteUTF8(manifest.PackageVersion);
@ -111,6 +112,7 @@ namespace YooAsset
manifest.LocationToLower = buffer.ReadBool();
manifest.IncludeAssetGUID = buffer.ReadBool();
manifest.OutputNameStyle = buffer.ReadInt32();
manifest.BuildBundleType = buffer.ReadInt32();
manifest.BuildPipeline = buffer.ReadUTF8();
manifest.PackageName = buffer.ReadUTF8();
manifest.PackageVersion = buffer.ReadUTF8();
@ -122,7 +124,7 @@ namespace YooAsset
// 读取资源列表
int packageAssetCount = buffer.ReadInt32();
manifest.AssetList = new List<PackageAsset>(packageAssetCount);
CreateAssetCollection(manifest, packageAssetCount);
for (int i = 0; i < packageAssetCount; i++)
{
var packageAsset = new PackageAsset();
@ -131,12 +133,12 @@ namespace YooAsset
packageAsset.AssetGUID = buffer.ReadUTF8();
packageAsset.AssetTags = buffer.ReadUTF8Array();
packageAsset.BundleID = buffer.ReadInt32();
manifest.AssetList.Add(packageAsset);
FillAssetCollection(manifest, packageAsset);
}
// 读取资源包列表
int packageBundleCount = buffer.ReadInt32();
manifest.BundleList = new List<PackageBundle>(packageBundleCount);
CreateBundleCollection(manifest, packageBundleCount);
for (int i = 0; i < packageBundleCount; i++)
{
var packageBundle = new PackageBundle();
@ -148,36 +150,129 @@ namespace YooAsset
packageBundle.Encrypted = buffer.ReadBool();
packageBundle.Tags = buffer.ReadUTF8Array();
packageBundle.DependIDs = buffer.ReadInt32Array();
manifest.BundleList.Add(packageBundle);
FillBundleCollection(manifest, packageBundle);
}
}
// 填充BundleDic
manifest.BundleDic1 = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
manifest.BundleDic2 = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
foreach (var packageBundle in manifest.BundleList)
{
packageBundle.ParseBundle(manifest);
manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle);
manifest.BundleDic2.Add(packageBundle.FileName, packageBundle);
}
// 填充AssetDic
manifest.AssetDic = new Dictionary<string, PackageAsset>(manifest.AssetList.Count);
foreach (var packageAsset in manifest.AssetList)
{
// 注意:我们不允许原始路径存在重名
string assetPath = packageAsset.AssetPath;
if (manifest.AssetDic.ContainsKey(assetPath))
throw new Exception($"AssetPath have existed : {assetPath}");
else
manifest.AssetDic.Add(assetPath, packageAsset);
}
// 初始化资源清单
InitManifest(manifest);
return manifest;
}
#endif
#region 解析资源清单辅助方法
public static void InitManifest(PackageManifest manifest)
{
// 填充资源包内包含的主资源列表
foreach (var packageAsset in manifest.AssetList)
{
int bundleID = packageAsset.BundleID;
if (bundleID >= 0 && bundleID < manifest.BundleList.Count)
{
var packageBundle = manifest.BundleList[bundleID];
packageBundle.IncludeMainAssets.Add(packageAsset);
}
else
{
throw new Exception($"Invalid bundle id : {bundleID} Asset path : {packageAsset.AssetPath}");
}
}
}
public static void CreateAssetCollection(PackageManifest manifest, int assetCount)
{
manifest.AssetList = new List<PackageAsset>(assetCount);
manifest.AssetDic = new Dictionary<string, PackageAsset>(assetCount);
if (manifest.EnableAddressable)
manifest.AssetPathMapping1 = new Dictionary<string, string>(assetCount * 3);
else
manifest.AssetPathMapping1 = new Dictionary<string, string>(assetCount * 2);
if (manifest.IncludeAssetGUID)
manifest.AssetPathMapping2 = new Dictionary<string, string>(assetCount);
else
manifest.AssetPathMapping2 = new Dictionary<string, string>();
}
public static void FillAssetCollection(PackageManifest manifest, PackageAsset packageAsset)
{
// 添加到列表集合
manifest.AssetList.Add(packageAsset);
// 注意:我们不允许原始路径存在重名
string assetPath = packageAsset.AssetPath;
if (manifest.AssetDic.ContainsKey(assetPath))
throw new System.Exception($"AssetPath have existed : {assetPath}");
else
manifest.AssetDic.Add(assetPath, packageAsset);
// 填充AssetPathMapping1
{
string location = packageAsset.AssetPath;
if (manifest.LocationToLower)
location = location.ToLower();
// 添加原生路径的映射
if (manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Location have existed : {location}");
else
manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
// 添加无后缀名路径的映射
string locationWithoutExtension = Path.ChangeExtension(location, null);
if (ReferenceEquals(location, locationWithoutExtension) == false)
{
if (manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension))
YooLogger.Warning($"Location have existed : {locationWithoutExtension}");
else
manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath);
}
}
// 添加可寻址地址
if (manifest.EnableAddressable)
{
string location = packageAsset.Address;
if (string.IsNullOrEmpty(location) == false)
{
if (manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Location have existed : {location}");
else
manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
}
}
// 填充AssetPathMapping2
if (manifest.IncludeAssetGUID)
{
if (manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID))
throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}");
else
manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath);
}
}
public static void CreateBundleCollection(PackageManifest manifest, int bundleCount)
{
manifest.BundleList = new List<PackageBundle>(bundleCount);
manifest.BundleDic1 = new Dictionary<string, PackageBundle>(bundleCount);
manifest.BundleDic2 = new Dictionary<string, PackageBundle>(bundleCount);
manifest.BundleDic3 = new Dictionary<string, PackageBundle>(bundleCount);
}
public static void FillBundleCollection(PackageManifest manifest, PackageBundle packageBundle)
{
// 初始化资源包
packageBundle.InitBundle(manifest);
// 添加到列表集合
manifest.BundleList.Add(packageBundle);
manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle);
manifest.BundleDic2.Add(packageBundle.FileName, packageBundle);
manifest.BundleDic3.Add(packageBundle.BundleGUID, packageBundle);
}
#endregion
/// <summary>
/// 注意:该类拷贝自编辑器
/// </summary>

View File

@ -1,6 +1,7 @@
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System;
namespace YooAsset
{
@ -14,6 +15,7 @@ namespace YooAsset
DeserializeAssetList,
PrepareBundleList,
DeserializeBundleList,
InitManifest,
Done,
}
@ -80,6 +82,7 @@ namespace YooAsset
Manifest.LocationToLower = _buffer.ReadBool();
Manifest.IncludeAssetGUID = _buffer.ReadBool();
Manifest.OutputNameStyle = _buffer.ReadInt32();
Manifest.BuildBundleType = _buffer.ReadInt32();
Manifest.BuildPipeline = _buffer.ReadUTF8();
Manifest.PackageName = _buffer.ReadUTF8();
Manifest.PackageVersion = _buffer.ReadUTF8();
@ -95,20 +98,8 @@ namespace YooAsset
if (_steps == ESteps.PrepareAssetList)
{
_packageAssetCount = _buffer.ReadInt32();
Manifest.AssetList = new List<PackageAsset>(_packageAssetCount);
Manifest.AssetDic = new Dictionary<string, PackageAsset>(_packageAssetCount);
if (Manifest.EnableAddressable)
Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount * 3);
else
Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount * 2);
if (Manifest.IncludeAssetGUID)
Manifest.AssetPathMapping2 = new Dictionary<string, string>(_packageAssetCount);
else
Manifest.AssetPathMapping2 = new Dictionary<string, string>();
_progressTotalValue = _packageAssetCount;
ManifestTools.CreateAssetCollection(Manifest, _packageAssetCount);
_steps = ESteps.DeserializeAssetList;
}
if (_steps == ESteps.DeserializeAssetList)
@ -121,57 +112,7 @@ namespace YooAsset
packageAsset.AssetGUID = _buffer.ReadUTF8();
packageAsset.AssetTags = _buffer.ReadUTF8Array();
packageAsset.BundleID = _buffer.ReadInt32();
Manifest.AssetList.Add(packageAsset);
// 注意:我们不允许原始路径存在重名
string assetPath = packageAsset.AssetPath;
if (Manifest.AssetDic.ContainsKey(assetPath))
throw new System.Exception($"AssetPath have existed : {assetPath}");
else
Manifest.AssetDic.Add(assetPath, packageAsset);
// 填充AssetPathMapping1
{
string location = packageAsset.AssetPath;
if (Manifest.LocationToLower)
location = location.ToLower();
// 添加原生路径的映射
if (Manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Location have existed : {location}");
else
Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
// 添加无后缀名路径的映射
string locationWithoutExtension = Path.ChangeExtension(location, null);
if (ReferenceEquals(location, locationWithoutExtension) == false)
{
if (Manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension))
YooLogger.Warning($"Location have existed : {locationWithoutExtension}");
else
Manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath);
}
}
if (Manifest.EnableAddressable)
{
string location = packageAsset.Address;
if (string.IsNullOrEmpty(location) == false)
{
if (Manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Location have existed : {location}");
else
Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
}
}
// 填充AssetPathMapping2
if (Manifest.IncludeAssetGUID)
{
if (Manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID))
throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}");
else
Manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath);
}
ManifestTools.FillAssetCollection(Manifest, packageAsset);
_packageAssetCount--;
Progress = 1f - _packageAssetCount / _progressTotalValue;
@ -188,11 +129,8 @@ namespace YooAsset
if (_steps == ESteps.PrepareBundleList)
{
_packageBundleCount = _buffer.ReadInt32();
Manifest.BundleList = new List<PackageBundle>(_packageBundleCount);
Manifest.BundleDic1 = new Dictionary<string, PackageBundle>(_packageBundleCount);
Manifest.BundleDic2 = new Dictionary<string, PackageBundle>(_packageBundleCount);
Manifest.BundleDic3 = new Dictionary<string, PackageBundle>(_packageBundleCount);
_progressTotalValue = _packageBundleCount;
ManifestTools.CreateBundleCollection(Manifest, _packageBundleCount);
_steps = ESteps.DeserializeBundleList;
}
if (_steps == ESteps.DeserializeBundleList)
@ -208,14 +146,7 @@ namespace YooAsset
packageBundle.Encrypted = _buffer.ReadBool();
packageBundle.Tags = _buffer.ReadUTF8Array();
packageBundle.DependIDs = _buffer.ReadInt32Array();
packageBundle.ParseBundle(Manifest);
Manifest.BundleList.Add(packageBundle);
Manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle);
Manifest.BundleDic2.Add(packageBundle.FileName, packageBundle);
// 注意原始文件可能存在相同的BundleGUID
if (Manifest.BundleDic3.ContainsKey(packageBundle.BundleGUID) == false)
Manifest.BundleDic3.Add(packageBundle.BundleGUID, packageBundle);
ManifestTools.FillBundleCollection(Manifest, packageBundle);
_packageBundleCount--;
Progress = 1f - _packageBundleCount / _progressTotalValue;
@ -225,10 +156,16 @@ namespace YooAsset
if (_packageBundleCount <= 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
_steps = ESteps.InitManifest;
}
}
if (_steps == ESteps.InitManifest)
{
ManifestTools.InitManifest(Manifest);
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
catch (System.Exception e)
{

View File

@ -31,6 +31,12 @@ namespace YooAsset
/// </summary>
public int BundleID;
/// <summary>
/// 所属资源包名称(仅编辑器有效)
/// </summary>
[NonSerialized]
public string BundleNameInEditor;
/// <summary>
/// 是否包含Tag
/// </summary>

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Collections.Generic;
namespace YooAsset
{
@ -46,17 +47,6 @@ namespace YooAsset
/// </summary>
public int[] DependIDs;
/// <summary>
/// 所属的包裹名称
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 所属的构建管线
/// </summary>
public string BuildPipeline { private set; get; }
/// <summary>
/// 资源包GUID
/// </summary>
@ -65,6 +55,18 @@ namespace YooAsset
get { return FileHash; }
}
/// <summary>
/// 资源包类型
/// </summary>
private int _bundleType;
public int BundleType
{
get
{
return _bundleType;
}
}
/// <summary>
/// 文件名称
/// </summary>
@ -93,18 +95,23 @@ namespace YooAsset
}
}
/// <summary>
/// 包含的主资源集合
/// </summary>
[NonSerialized]
public readonly List<PackageAsset> IncludeMainAssets = new List<PackageAsset>(10);
public PackageBundle()
{
}
/// <summary>
/// 解析资源包
/// 初始化资源包
/// </summary>
public void ParseBundle(PackageManifest manifest)
public void InitBundle(PackageManifest manifest)
{
PackageName = manifest.PackageName;
BuildPipeline = manifest.BuildPipeline;
_bundleType = manifest.BuildBundleType;
_fileExtension = ManifestTools.GetRemoteBundleFileExtension(BundleName);
_fileName = ManifestTools.GetRemoteBundleFileName(manifest.OutputNameStyle, BundleName, _fileExtension, FileHash);
}

View File

@ -28,6 +28,11 @@ namespace YooAsset
/// </summary>
public int OutputNameStyle;
/// <summary>
/// 构建资源包类型
/// </summary>
public int BuildBundleType;
/// <summary>
/// 构建管线名称
/// </summary>

View File

@ -37,6 +37,11 @@ namespace YooAsset
/// </summary>
public int OutputNameStyle;
/// <summary>
/// 构建资源包类型
/// </summary>
public int BuildBundleType;
/// <summary>
/// 构建管线名称
/// </summary>
@ -67,6 +72,23 @@ namespace YooAsset
/// </summary>
public List<PackageBundle> BundleList = new List<PackageBundle>();
/// <summary>
/// 资源映射集合提供AssetPath获取PackageAsset
/// </summary>
[NonSerialized]
public Dictionary<string, PackageAsset> AssetDic;
/// <summary>
/// 资源路径映射集合提供Location获取AssetPath
/// </summary>
[NonSerialized]
public Dictionary<string, string> AssetPathMapping1;
/// <summary>
/// 资源路径映射集合提供AssetGUID获取AssetPath
/// </summary>
[NonSerialized]
public Dictionary<string, string> AssetPathMapping2;
/// <summary>
/// 资源包集合提供BundleName获取PackageBundle
@ -86,24 +108,6 @@ namespace YooAsset
[NonSerialized]
public Dictionary<string, PackageBundle> BundleDic3;
/// <summary>
/// 资源映射集合提供AssetPath获取PackageAsset
/// </summary>
[NonSerialized]
public Dictionary<string, PackageAsset> AssetDic;
/// <summary>
/// 资源路径映射集合提供Location获取AssetPath
/// </summary>
[NonSerialized]
public Dictionary<string, string> AssetPathMapping1;
/// <summary>
/// 资源路径映射集合提供AssetGUID获取AssetPath
/// </summary>
[NonSerialized]
public Dictionary<string, string> AssetPathMapping2;
/// <summary>
/// 获取包裹的详细信息
@ -116,6 +120,7 @@ namespace YooAsset
details.LocationToLower = LocationToLower;
details.IncludeAssetGUID = IncludeAssetGUID;
details.OutputNameStyle = OutputNameStyle;
details.BuildBundleType = BuildBundleType;
details.BuildPipeline = BuildPipeline;
details.PackageName = PackageName;
details.PackageVersion = PackageVersion;
@ -357,25 +362,6 @@ 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

@ -3,6 +3,14 @@ namespace YooAsset
{
public class EditorSimulateBuildParam
{
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 模拟构建管线名称
/// </summary>
public string BuildPipelineName = "EditorSimulateBuildPipeline";
}
}

View File

@ -106,7 +106,6 @@ namespace YooAsset
if (EditorFileSystem.Belong(packageBundle))
{
BundleInfo bundleInfo = new BundleInfo(EditorFileSystem, packageBundle);
bundleInfo.IncludeAssetsInEditor = ActiveManifest.GetBundleIncludeAssets(assetInfo.AssetPath);
return bundleInfo;
}

View File

@ -20,20 +20,36 @@ namespace YooAsset
/// </summary>
public uint FileLoadCRC;
}
public struct DecryptResult
{
/// <summary>
/// 资源包对象
/// </summary>
public AssetBundle Result;
/// <summary>
/// 异步请求句柄
/// </summary>
public AssetBundleCreateRequest CreateRequest;
/// <summary>
/// 托管流对象
/// 注意:流对象在资源包对象释放的时候会自动释放
/// </summary>
public Stream ManagedStream;
}
public interface IDecryptionServices
{
/// <summary>
/// 同步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
AssetBundle LoadAssetBundle(DecryptFileInfo fileInfo, out Stream managedStream);
DecryptResult LoadAssetBundle(DecryptFileInfo fileInfo);
/// <summary>
/// 异步方式获取解密的资源包对象
/// 注意:加载流对象在资源包对象释放的时候会自动释放
/// </summary>
AssetBundleCreateRequest LoadAssetBundleAsync(DecryptFileInfo fileInfo, out Stream managedStream);
DecryptResult LoadAssetBundleAsync(DecryptFileInfo fileInfo);
/// <summary>
/// 获取解密的字节数据