diff --git a/Assets/YooAsset/Runtime/InitializeParameters.cs b/Assets/YooAsset/Runtime/InitializeParameters.cs
new file mode 100644
index 0000000..961df17
--- /dev/null
+++ b/Assets/YooAsset/Runtime/InitializeParameters.cs
@@ -0,0 +1,96 @@
+using UnityEngine;
+
+namespace YooAsset
+{
+ ///
+ /// 初始化参数
+ ///
+ public abstract class InitializeParameters
+ {
+ ///
+ /// 资源定位地址大小写不敏感
+ ///
+ public bool LocationToLower = false;
+
+ ///
+ /// 资源定位服务接口
+ ///
+ public ILocationServices LocationServices = null;
+
+ ///
+ /// 文件解密服务接口
+ ///
+ public IDecryptionServices DecryptionServices = null;
+
+ ///
+ /// 资源加载的最大数量
+ ///
+ public int AssetLoadingMaxNumber = int.MaxValue;
+
+ ///
+ /// 异步操作系统每帧允许运行的最大时间切片(单位:毫秒)
+ ///
+ public long OperationSystemMaxTimeSlice = long.MaxValue;
+ }
+
+ ///
+ /// 编辑器下模拟运行模式的初始化参数
+ ///
+ public class EditorSimulateModeParameters : InitializeParameters
+ {
+ ///
+ /// 用于模拟运行的资源清单路径
+ /// 注意:如果路径为空,会自动重新构建补丁清单。
+ ///
+ public string SimulatePatchManifestPath;
+ }
+
+ ///
+ /// 离线运行模式的初始化参数
+ ///
+ public class OfflinePlayModeParameters : InitializeParameters
+ {
+ ///
+ /// 内置的资源包裹名称
+ ///
+ public string BuildinPackageName = string.Empty;
+ }
+
+ ///
+ /// 联机运行模式的初始化参数
+ ///
+ public class HostPlayModeParameters : InitializeParameters
+ {
+ ///
+ /// 默认的资源服务器下载地址
+ ///
+ public string DefaultHostServer;
+
+ ///
+ /// 备用的资源服务器下载地址
+ ///
+ public string FallbackHostServer;
+
+#if UNITY_WEBGL
+ ///
+ /// WEBGL模式不支持多线程下载
+ ///
+ internal int BreakpointResumeFileSize = int.MaxValue;
+#else
+ ///
+ /// 启用断点续传功能的文件大小
+ ///
+ public int BreakpointResumeFileSize = int.MaxValue;
+#endif
+
+ ///
+ /// 下载文件校验等级
+ ///
+ public EVerifyLevel VerifyLevel = EVerifyLevel.High;
+
+ ///
+ /// 查询服务类
+ ///
+ public IQueryServices QueryServices = null;
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/InitializeParameters.cs.meta b/Assets/YooAsset/Runtime/InitializeParameters.cs.meta
new file mode 100644
index 0000000..792e109
--- /dev/null
+++ b/Assets/YooAsset/Runtime/InitializeParameters.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a9b5e8a77215adb45b203be8a4fb9eda
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/YooAssetComponent.cs b/Assets/YooAsset/Runtime/YooAssetComponent.cs
new file mode 100644
index 0000000..bb14bf3
--- /dev/null
+++ b/Assets/YooAsset/Runtime/YooAssetComponent.cs
@@ -0,0 +1,1087 @@
+using System;
+using System.Diagnostics;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine.SceneManagement;
+
+namespace YooAsset
+{
+ public class YooAssetComponent
+ {
+ ///
+ /// 运行模式
+ ///
+ public enum EPlayMode
+ {
+ ///
+ /// 编辑器下的模拟模式
+ /// 注意:在初始化的时候自动构建真机模拟环境。
+ ///
+ EditorSimulateMode,
+
+ ///
+ /// 离线运行模式
+ ///
+ OfflinePlayMode,
+
+ ///
+ /// 联机运行模式
+ ///
+ HostPlayMode,
+ }
+
+ private bool _isInitialize = false;
+ private string _initializeError = string.Empty;
+ private EOperationStatus _initializeStatus = EOperationStatus.None;
+ private EPlayMode _playMode;
+ private IBundleServices _bundleServices;
+ private ILocationServices _locationServices;
+ private EditorSimulateModeImpl _editorSimulateModeImpl;
+ private OfflinePlayModeImpl _offlinePlayModeImpl;
+ private HostPlayModeImpl _hostPlayModeImpl;
+
+
+ ///
+ /// 是否已经初始化
+ ///
+ public bool IsInitialized
+ {
+ get { return _isInitialize; }
+ }
+
+ ///
+ /// 异步初始化
+ ///
+ public InitializationOperation InitializeAsync(InitializeParameters parameters)
+ {
+ if (parameters == null)
+ throw new Exception($"YooAsset create parameters is null.");
+
+#if !UNITY_EDITOR
+ if (parameters is EditorSimulateModeParameters)
+ throw new Exception($"Editor simulate mode only support unity editor.");
+#endif
+
+ // 鉴定运行模式
+ if (parameters is EditorSimulateModeParameters)
+ _playMode = EPlayMode.EditorSimulateMode;
+ else if (parameters is OfflinePlayModeParameters)
+ _playMode = EPlayMode.OfflinePlayMode;
+ else if (parameters is HostPlayModeParameters)
+ _playMode = EPlayMode.HostPlayMode;
+ else
+ throw new NotImplementedException();
+
+ if (parameters.LocationServices == null)
+ throw new Exception($"{nameof(IBundleServices)} is null.");
+
+ if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ var playModeParameters = parameters as OfflinePlayModeParameters;
+ if (string.IsNullOrEmpty(playModeParameters.BuildinPackageName))
+ throw new Exception($"{nameof(playModeParameters.BuildinPackageName)} is empty.");
+ }
+
+ if (_playMode == EPlayMode.HostPlayMode)
+ {
+ var playModeParameters = parameters as HostPlayModeParameters;
+ if (playModeParameters.QueryServices == null)
+ throw new Exception($"{nameof(IQueryServices)} is null.");
+ }
+
+ if (_isInitialize)
+ {
+ throw new Exception("YooAsset is initialized yet.");
+ }
+
+ _locationServices = parameters.LocationServices;
+
+ // 检测参数范围
+ if (parameters.AssetLoadingMaxNumber < 1)
+ {
+ parameters.AssetLoadingMaxNumber = 1;
+ YooLogger.Warning($"{nameof(parameters.AssetLoadingMaxNumber)} minimum value is 1");
+ }
+ if (parameters.OperationSystemMaxTimeSlice < 30)
+ {
+ parameters.OperationSystemMaxTimeSlice = 30;
+ YooLogger.Warning($"{nameof(parameters.OperationSystemMaxTimeSlice)} minimum value is 30 milliseconds");
+ }
+
+ // 创建驱动器
+ if (_isInitialize == false)
+ {
+ _isInitialize = true;
+ UnityEngine.GameObject driverGo = new UnityEngine.GameObject("[YooAsset]");
+ driverGo.AddComponent();
+ UnityEngine.Object.DontDestroyOnLoad(driverGo);
+
+#if DEBUG
+ driverGo.AddComponent();
+#endif
+ }
+
+ // 初始化异步系统
+ OperationSystem.Initialize(parameters.OperationSystemMaxTimeSlice);
+
+ // 初始化下载系统
+ if (_playMode == EPlayMode.HostPlayMode)
+ {
+ var hostPlayModeParameters = parameters as HostPlayModeParameters;
+ CacheSystem.Initialize(hostPlayModeParameters.VerifyLevel);
+ DownloadSystem.Initialize(hostPlayModeParameters.BreakpointResumeFileSize);
+ }
+ else
+ {
+ CacheSystem.Initialize(EVerifyLevel.Low);
+ DownloadSystem.Initialize(int.MaxValue);
+ }
+
+ // 初始化资源系统
+ InitializationOperation initializeOperation;
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ _editorSimulateModeImpl = new EditorSimulateModeImpl();
+ _bundleServices = _editorSimulateModeImpl;
+ AssetSystem.Initialize(true, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
+ var simulateModeParameters = parameters as EditorSimulateModeParameters;
+ initializeOperation = _editorSimulateModeImpl.InitializeAsync(
+ simulateModeParameters.LocationToLower,
+ simulateModeParameters.SimulatePatchManifestPath);
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ _offlinePlayModeImpl = new OfflinePlayModeImpl();
+ _bundleServices = _offlinePlayModeImpl;
+ AssetSystem.Initialize(false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
+ var playModeParameters = parameters as OfflinePlayModeParameters;
+ initializeOperation = _offlinePlayModeImpl.InitializeAsync(
+ playModeParameters.LocationToLower,
+ playModeParameters.BuildinPackageName);
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ _hostPlayModeImpl = new HostPlayModeImpl();
+ _bundleServices = _hostPlayModeImpl;
+ AssetSystem.Initialize(false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
+ var playModeParameters = parameters as HostPlayModeParameters;
+ initializeOperation = _hostPlayModeImpl.InitializeAsync(
+ playModeParameters.LocationToLower,
+ playModeParameters.DefaultHostServer,
+ playModeParameters.FallbackHostServer,
+ playModeParameters.QueryServices);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+
+ // 监听初始化结果
+ initializeOperation.Completed += InitializeOperation_Completed;
+ return initializeOperation;
+ }
+ private void InitializeOperation_Completed(AsyncOperationBase op)
+ {
+ _initializeStatus = op.Status;
+ _initializeError = op.Error;
+ }
+
+ ///
+ /// 向网络端请求静态资源版本
+ ///
+ /// 更新的资源包裹名称
+ /// 超时时间(默认值:60秒)
+ public UpdateStaticVersionOperation UpdateStaticVersionAsync(string packageName, int timeout = 60)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ var operation = new EditorPlayModeUpdateStaticVersionOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ var operation = new OfflinePlayModeUpdateStaticVersionOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.UpdateStaticVersionAsync(packageName, timeout);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// 向网络端请求并更新补丁清单
+ ///
+ /// 更新的资源包裹名称
+ /// 更新的资源包裹版本
+ /// 超时时间(默认值:60秒)
+ public UpdateManifestOperation UpdateManifestAsync(string packageName, string packageCRC, int timeout = 60)
+ {
+ DebugCheckInitialize();
+ DebugCheckUpdateManifest();
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ var operation = new EditorPlayModeUpdateManifestOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ var operation = new OfflinePlayModeUpdateManifestOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.UpdatePatchManifestAsync(packageName, packageCRC, timeout);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// 弱联网情况下加载补丁清单
+ /// 注意:当指定版本内容验证失败后会返回失败。
+ ///
+ /// 指定的资源包裹名称
+ /// 指定的资源包裹版本
+ public UpdateManifestOperation WeaklyUpdateManifestAsync(string packageName, string packageCRC)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ var operation = new EditorPlayModeUpdateManifestOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ var operation = new OfflinePlayModeUpdateManifestOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.WeaklyUpdatePatchManifestAsync(packageName, packageCRC);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// 开启一个异步操作
+ ///
+ /// 异步操作对象
+ public void StartOperation(GameAsyncOperation operation)
+ {
+ OperationSystem.StartOperation(operation);
+ }
+
+ ///
+ /// 资源回收(卸载引用计数为零的资源)
+ ///
+ public void UnloadUnusedAssets()
+ {
+ if (_isInitialize)
+ {
+ AssetSystem.Update();
+ AssetSystem.UnloadUnusedAssets();
+ }
+ }
+
+ ///
+ /// 强制回收所有资源
+ ///
+ public void ForceUnloadAllAssets()
+ {
+ if (_isInitialize)
+ {
+ AssetSystem.ForceUnloadAllAssets();
+ }
+ }
+
+
+ #region 资源信息
+ ///
+ /// 是否需要从远端更新下载
+ ///
+ /// 资源的定位地址
+ public bool IsNeedDownloadFromRemote(string location)
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
+ if (assetInfo.IsInvalid)
+ return false;
+
+ BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
+ if (bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
+ return true;
+ else
+ return false;
+ }
+
+ ///
+ /// 是否需要从远端更新下载
+ ///
+ /// 资源的定位地址
+ public bool IsNeedDownloadFromRemote(AssetInfo assetInfo)
+ {
+ DebugCheckInitialize();
+ if (assetInfo.IsInvalid)
+ {
+ YooLogger.Warning(assetInfo.Error);
+ return false;
+ }
+
+ BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
+ if (bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
+ return true;
+ else
+ return false;
+ }
+
+ ///
+ /// 获取资源信息列表
+ ///
+ /// 资源标签
+ public AssetInfo[] GetAssetInfos(string tag)
+ {
+ DebugCheckInitialize();
+ string[] tags = new string[] { tag };
+ return _bundleServices.GetAssetInfos(tags);
+ }
+
+ ///
+ /// 获取资源信息列表
+ ///
+ /// 资源标签列表
+ public AssetInfo[] GetAssetInfos(string[] tags)
+ {
+ DebugCheckInitialize();
+ return _bundleServices.GetAssetInfos(tags);
+ }
+
+ ///
+ /// 获取资源信息
+ ///
+ /// 资源的定位地址
+ public AssetInfo GetAssetInfo(string location)
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
+ return assetInfo;
+ }
+
+ ///
+ /// 获取资源路径
+ ///
+ /// 资源的定位地址
+ /// 如果location地址无效,则返回空字符串
+ public string GetAssetPath(string location)
+ {
+ DebugCheckInitialize();
+ return _locationServices.ConvertLocationToAssetPath(location);
+ }
+ #endregion
+
+ #region 原生文件
+ ///
+ /// 异步获取原生文件
+ ///
+ /// 资源的定位地址
+ /// 拷贝路径
+ public RawFileOperation GetRawFileAsync(string location, string copyPath = null)
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
+ return GetRawFileInternal(assetInfo, copyPath);
+ }
+
+ ///
+ /// 异步获取原生文件
+ ///
+ /// 资源信息
+ /// 拷贝路径
+ public RawFileOperation GetRawFileAsync(AssetInfo assetInfo, string copyPath = null)
+ {
+ DebugCheckInitialize();
+ if (assetInfo.IsInvalid)
+ YooLogger.Warning(assetInfo.Error);
+ return GetRawFileInternal(assetInfo, copyPath);
+ }
+
+
+ private RawFileOperation GetRawFileInternal(AssetInfo assetInfo, string copyPath)
+ {
+ if (assetInfo.IsInvalid)
+ {
+ RawFileOperation operation = new CompletedRawFileOperation(assetInfo.Error, copyPath);
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+
+ BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
+
+#if UNITY_EDITOR
+ if (bundleInfo.Bundle.IsRawFile == false)
+ {
+ string error = $"Cannot load asset bundle file using {nameof(GetRawFileAsync)} method !";
+ YooLogger.Error(error);
+ RawFileOperation operation = new CompletedRawFileOperation(error, copyPath);
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+#endif
+
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ RawFileOperation operation = new EditorPlayModeRawFileOperation(bundleInfo, copyPath);
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ RawFileOperation operation = new OfflinePlayModeRawFileOperation(bundleInfo, copyPath);
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ RawFileOperation operation = new HostPlayModeRawFileOperation(bundleInfo, copyPath);
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+ #endregion
+
+ #region 场景加载
+ ///
+ /// 异步加载场景
+ ///
+ /// 场景的定位地址
+ /// 场景加载模式
+ /// 加载完毕时是否主动激活
+ /// 优先级
+ public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
+ var handle = AssetSystem.LoadSceneAsync(assetInfo, sceneMode, activateOnLoad, priority);
+ return handle;
+ }
+
+ ///
+ /// 异步加载场景
+ ///
+ /// 场景的资源信息
+ /// 场景加载模式
+ /// 加载完毕时是否主动激活
+ /// 优先级
+ public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
+ {
+ DebugCheckInitialize();
+ if (assetInfo.IsInvalid)
+ YooLogger.Warning(assetInfo.Error);
+ var handle = AssetSystem.LoadSceneAsync(assetInfo, sceneMode, activateOnLoad, priority);
+ return handle;
+ }
+ #endregion
+
+ #region 资源加载
+ ///
+ /// 同步加载资源对象
+ ///
+ /// 资源信息
+ public AssetOperationHandle LoadAssetSync(AssetInfo assetInfo)
+ {
+ DebugCheckInitialize();
+ if (assetInfo.IsInvalid)
+ YooLogger.Warning(assetInfo.Error);
+ return LoadAssetInternal(assetInfo, true);
+ }
+
+ ///
+ /// 同步加载资源对象
+ ///
+ /// 资源类型
+ /// 资源的定位地址
+ public AssetOperationHandle LoadAssetSync(string location) where TObject : UnityEngine.Object
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
+ return LoadAssetInternal(assetInfo, true);
+ }
+
+ ///
+ /// 同步加载资源对象
+ ///
+ /// 资源的定位地址
+ /// 资源类型
+ public AssetOperationHandle LoadAssetSync(string location, System.Type type)
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
+ return LoadAssetInternal(assetInfo, true);
+ }
+
+
+ ///
+ /// 异步加载资源对象
+ ///
+ /// 资源信息
+ public AssetOperationHandle LoadAssetAsync(AssetInfo assetInfo)
+ {
+ DebugCheckInitialize();
+ if (assetInfo.IsInvalid)
+ YooLogger.Warning(assetInfo.Error);
+ return LoadAssetInternal(assetInfo, false);
+ }
+
+ ///
+ /// 异步加载资源对象
+ ///
+ /// 资源类型
+ /// 资源的定位地址
+ public AssetOperationHandle LoadAssetAsync(string location) where TObject : UnityEngine.Object
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
+ return LoadAssetInternal(assetInfo, false);
+ }
+
+ ///
+ /// 异步加载资源对象
+ ///
+ /// 资源的定位地址
+ /// 资源类型
+ public AssetOperationHandle LoadAssetAsync(string location, System.Type type)
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
+ return LoadAssetInternal(assetInfo, false);
+ }
+
+
+ private AssetOperationHandle LoadAssetInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
+ {
+#if UNITY_EDITOR
+ BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
+ if (bundleInfo.Bundle.IsRawFile)
+ {
+ string error = $"Cannot load raw file using LoadAsset method !";
+ YooLogger.Error(error);
+ CompletedProvider completedProvider = new CompletedProvider(assetInfo);
+ completedProvider.SetCompleted(error);
+ return completedProvider.CreateHandle();
+ }
+#endif
+
+ var handle = AssetSystem.LoadAssetAsync(assetInfo);
+ if (waitForAsyncComplete)
+ handle.WaitForAsyncComplete();
+ return handle;
+ }
+ #endregion
+
+ #region 资源加载
+ ///
+ /// 同步加载子资源对象
+ ///
+ /// 资源信息
+ public SubAssetsOperationHandle LoadSubAssetsSync(AssetInfo assetInfo)
+ {
+ DebugCheckInitialize();
+ if (assetInfo.IsInvalid)
+ YooLogger.Warning(assetInfo.Error);
+ return LoadSubAssetsInternal(assetInfo, true);
+ }
+
+ ///
+ /// 同步加载子资源对象
+ ///
+ /// 资源类型
+ /// 资源的定位地址
+ public SubAssetsOperationHandle LoadSubAssetsSync(string location) where TObject : UnityEngine.Object
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
+ return LoadSubAssetsInternal(assetInfo, true);
+ }
+
+ ///
+ /// 同步加载子资源对象
+ ///
+ /// 资源的定位地址
+ /// 子对象类型
+ public SubAssetsOperationHandle LoadSubAssetsSync(string location, System.Type type)
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
+ return LoadSubAssetsInternal(assetInfo, true);
+ }
+
+
+ ///
+ /// 异步加载子资源对象
+ ///
+ /// 资源信息
+ public SubAssetsOperationHandle LoadSubAssetsAsync(AssetInfo assetInfo)
+ {
+ DebugCheckInitialize();
+ if (assetInfo.IsInvalid)
+ YooLogger.Warning(assetInfo.Error);
+ return LoadSubAssetsInternal(assetInfo, false);
+ }
+
+ ///
+ /// 异步加载子资源对象
+ ///
+ /// 资源类型
+ /// 资源的定位地址
+ public SubAssetsOperationHandle LoadSubAssetsAsync(string location) where TObject : UnityEngine.Object
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
+ return LoadSubAssetsInternal(assetInfo, false);
+ }
+
+ ///
+ /// 异步加载子资源对象
+ ///
+ /// 资源的定位地址
+ /// 子对象类型
+ public SubAssetsOperationHandle LoadSubAssetsAsync(string location, System.Type type)
+ {
+ DebugCheckInitialize();
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
+ return LoadSubAssetsInternal(assetInfo, false);
+ }
+
+
+ private SubAssetsOperationHandle LoadSubAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
+ {
+#if UNITY_EDITOR
+ BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
+ if (bundleInfo.Bundle.IsRawFile)
+ {
+ string error = $"Cannot load raw file using LoadSubAssets method !";
+ YooLogger.Error(error);
+ CompletedProvider completedProvider = new CompletedProvider(assetInfo);
+ completedProvider.SetCompleted(error);
+ return completedProvider.CreateHandle();
+ }
+#endif
+
+ var handle = AssetSystem.LoadSubAssetsAsync(assetInfo);
+ if (waitForAsyncComplete)
+ handle.WaitForAsyncComplete();
+ return handle;
+ }
+ #endregion
+
+ #region 资源下载
+ ///
+ /// 创建补丁下载器,用于下载更新资源标签指定的资源包文件
+ ///
+ /// 资源标签
+ /// 同时下载的最大文件数
+ /// 下载失败的重试次数
+ public PatchDownloaderOperation CreatePatchDownloader(string tag, int downloadingMaxNumber, int failedTryAgain)
+ {
+ DebugCheckInitialize();
+ return CreatePatchDownloader(new string[] { tag }, downloadingMaxNumber, failedTryAgain);
+ }
+
+ ///
+ /// 创建补丁下载器,用于下载更新资源标签指定的资源包文件
+ ///
+ /// 资源标签列表
+ /// 同时下载的最大文件数
+ /// 下载失败的重试次数
+ public PatchDownloaderOperation CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode || _playMode == EPlayMode.OfflinePlayMode)
+ {
+ List downloadList = new List();
+ var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.CreatePatchDownloaderByTags(tags, downloadingMaxNumber, failedTryAgain);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// 创建补丁下载器,用于下载更新当前资源版本所有的资源包文件
+ ///
+ /// 同时下载的最大文件数
+ /// 下载失败的重试次数
+ public PatchDownloaderOperation CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode || _playMode == EPlayMode.OfflinePlayMode)
+ {
+ List downloadList = new List();
+ var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.CreatePatchDownloaderByAll(downloadingMaxNumber, failedTryAgain);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+
+ ///
+ /// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件
+ ///
+ /// 资源定位列表
+ /// 同时下载的最大文件数
+ /// 下载失败的重试次数
+ public PatchDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode || _playMode == EPlayMode.OfflinePlayMode)
+ {
+ List downloadList = new List();
+ var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ List assetInfos = new List(locations.Length);
+ foreach (var location in locations)
+ {
+ AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
+ assetInfos.Add(assetInfo);
+ }
+ return _hostPlayModeImpl.CreatePatchDownloaderByPaths(assetInfos.ToArray(), downloadingMaxNumber, failedTryAgain);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件
+ ///
+ /// 资源信息列表
+ /// 同时下载的最大文件数
+ /// 下载失败的重试次数
+ public PatchDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode || _playMode == EPlayMode.OfflinePlayMode)
+ {
+ List downloadList = new List();
+ var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.CreatePatchDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+ #endregion
+
+ #region 资源解压
+ ///
+ /// 创建补丁解压器
+ ///
+ /// 资源标签
+ /// 同时解压的最大文件数
+ /// 解压失败的重试次数
+ public PatchUnpackerOperation CreatePatchUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain)
+ {
+ DebugCheckInitialize();
+ return CreatePatchUnpacker(new string[] { tag }, unpackingMaxNumber, failedTryAgain);
+ }
+
+ ///
+ /// 创建补丁解压器
+ ///
+ /// 资源标签列表
+ /// 同时解压的最大文件数
+ /// 解压失败的重试次数
+ public PatchUnpackerOperation CreatePatchUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ List downloadList = new List();
+ var operation = new PatchUnpackerOperation(downloadList, unpackingMaxNumber, failedTryAgain);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ List downloadList = new List();
+ var operation = new PatchUnpackerOperation(downloadList, unpackingMaxNumber, failedTryAgain);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.CreatePatchUnpackerByTags(tags, unpackingMaxNumber, failedTryAgain);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// 创建补丁解压器
+ ///
+ /// 同时解压的最大文件数
+ /// 解压失败的重试次数
+ public PatchUnpackerOperation CreatePatchUnpacker(int unpackingMaxNumber, int failedTryAgain)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ List downloadList = new List();
+ var operation = new PatchUnpackerOperation(downloadList, unpackingMaxNumber, failedTryAgain);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ List downloadList = new List();
+ var operation = new PatchUnpackerOperation(downloadList, unpackingMaxNumber, failedTryAgain);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.CreatePatchUnpackerByAll(unpackingMaxNumber, failedTryAgain);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+ #endregion
+
+ #region 包裹更新
+ ///
+ /// 创建资源包裹下载器,用于下载更新指定资源版本所有的资源包文件
+ ///
+ /// 指定更新的资源包裹名称
+ /// 指定更新的资源包裹版本
+ /// 超时时间
+ public UpdatePackageOperation UpdatePackageAsync(string packageName, string packageCRC, int timeout = 60)
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ var operation = new EditorPlayModeUpdatePackageOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ var operation = new OfflinePlayModeUpdatePackageOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ return _hostPlayModeImpl.UpdatePackageAsync(packageName, packageCRC, timeout);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+ #endregion
+
+ #region 沙盒相关
+ ///
+ /// 获取沙盒的根路径
+ ///
+ public string GetSandboxRoot()
+ {
+ return PathHelper.MakePersistentRootPath();
+ }
+
+ ///
+ /// 清空沙盒目录
+ ///
+ public void ClearSandbox()
+ {
+ SandboxHelper.DeleteSandbox();
+ }
+
+ ///
+ /// 清空所有的缓存文件
+ ///
+ public void ClearAllCacheFiles()
+ {
+ SandboxHelper.DeleteCacheFolder();
+ }
+
+ ///
+ /// 清空未被使用的缓存文件
+ ///
+ public ClearUnusedCacheFilesOperation ClearUnusedCacheFiles()
+ {
+ DebugCheckInitialize();
+ if (_playMode == EPlayMode.EditorSimulateMode)
+ {
+ var operation = new EditorPlayModeClearUnusedCacheFilesOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.OfflinePlayMode)
+ {
+ var operation = new OfflinePlayModeClearUnusedCacheFilesOperation();
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else if (_playMode == EPlayMode.HostPlayMode)
+ {
+ var operation = new HostPlayModeClearUnusedCacheFilesOperation(_hostPlayModeImpl);
+ OperationSystem.StartOperation(operation);
+ return operation;
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+ #endregion
+
+ #region 内部方法
+ internal void InternalDestroy()
+ {
+ if (_isInitialize)
+ {
+ _isInitialize = false;
+ _initializeError = string.Empty;
+ _initializeStatus = EOperationStatus.None;
+
+ _bundleServices = null;
+ _locationServices = null;
+ _editorSimulateModeImpl = null;
+ _offlinePlayModeImpl = null;
+ _hostPlayModeImpl = null;
+
+ OperationSystem.DestroyAll();
+ DownloadSystem.DestroyAll();
+ CacheSystem.DestroyAll();
+ AssetSystem.DestroyAll();
+ YooLogger.Log("YooAssets destroy all !");
+ }
+ }
+ internal void InternalUpdate()
+ {
+ OperationSystem.Update();
+ DownloadSystem.Update();
+ AssetSystem.Update();
+ }
+
+ ///
+ /// 资源定位地址转换为资源完整路径
+ ///
+ internal string MappingToAssetPath(string location)
+ {
+ return _bundleServices.MappingToAssetPath(location);
+ }
+ #endregion
+
+ #region 调试方法
+ [Conditional("DEBUG")]
+ private void DebugCheckInitialize()
+ {
+ if (_initializeStatus == EOperationStatus.None)
+ throw new Exception("YooAssets initialize not completed !");
+ else if (_initializeStatus == EOperationStatus.Failed)
+ throw new Exception($"YooAssets initialize failed : {_initializeError}");
+ }
+
+ [Conditional("DEBUG")]
+ private void DebugCheckLocation(string location)
+ {
+ if (string.IsNullOrEmpty(location) == false)
+ {
+ // 检查路径末尾是否有空格
+ int index = location.LastIndexOf(" ");
+ if (index != -1)
+ {
+ if (location.Length == index + 1)
+ YooLogger.Warning($"Found blank character in location : \"{location}\"");
+ }
+
+ if (location.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0)
+ YooLogger.Warning($"Found illegal character in location : \"{location}\"");
+ }
+ }
+
+ [Conditional("DEBUG")]
+ private void DebugCheckUpdateManifest()
+ {
+ var loadedBundleInfos = AssetSystem.GetLoadedBundleInfos();
+ if (loadedBundleInfos.Count > 0)
+ {
+ YooLogger.Warning($"Found loaded bundle before update manifest ! Recommended to call the {nameof(ForceUnloadAllAssets)} method to release loaded bundle !");
+ }
+ }
+ #endregion
+
+ #region 私有方法
+ ///
+ /// 资源定位地址转换为资源信息类,失败时内部会发出错误日志。
+ ///
+ /// 如果转换失败会返回一个无效的资源信息类
+ private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
+ {
+ DebugCheckLocation(location);
+ string assetPath = _locationServices.ConvertLocationToAssetPath(location);
+ PatchAsset patchAsset = _bundleServices.TryGetPatchAsset(assetPath);
+ if (patchAsset != null)
+ {
+ AssetInfo assetInfo = new AssetInfo(patchAsset, assetType);
+ return assetInfo;
+ }
+ else
+ {
+ string error;
+ if (string.IsNullOrEmpty(location))
+ error = $"The location is null or empty !";
+ else
+ error = $"The location is invalid : {location}";
+ YooLogger.Error(error);
+ AssetInfo assetInfo = new AssetInfo(error);
+ return assetInfo;
+ }
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/YooAssetComponent.cs.meta b/Assets/YooAsset/Runtime/YooAssetComponent.cs.meta
new file mode 100644
index 0000000..8878911
--- /dev/null
+++ b/Assets/YooAsset/Runtime/YooAssetComponent.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6fcda791b973f5b4499e8bd3ede91312
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: