2022-09-28 14:39:58 +08:00
using System ;
using System.Diagnostics ;
using System.Collections ;
using System.Collections.Generic ;
using UnityEngine.SceneManagement ;
namespace YooAsset
{
2022-10-14 11:49:32 +08:00
public class AssetsPackage
2022-09-28 14:39:58 +08:00
{
private bool _isInitialize = false ;
private string _initializeError = string . Empty ;
private EOperationStatus _initializeStatus = EOperationStatus . None ;
private EPlayMode _playMode ;
private IBundleServices _bundleServices ;
2022-09-29 18:40:43 +08:00
private AssetSystemImpl _assetSystemImpl ;
2022-09-28 14:39:58 +08:00
private EditorSimulateModeImpl _editorSimulateModeImpl ;
private OfflinePlayModeImpl _offlinePlayModeImpl ;
private HostPlayModeImpl _hostPlayModeImpl ;
2022-09-29 18:40:43 +08:00
/// <summary>
/// 包裹名
/// </summary>
public string PackageName { private set ; get ; }
2022-09-28 14:39:58 +08:00
/// <summary>
2022-10-12 15:01:39 +08:00
/// 初始化状态
2022-09-28 14:39:58 +08:00
/// </summary>
2022-10-12 15:01:39 +08:00
public EOperationStatus InitializeStatus
2022-09-28 14:39:58 +08:00
{
2022-10-12 15:01:39 +08:00
get { return _initializeStatus ; }
2022-09-28 14:39:58 +08:00
}
2022-09-29 18:40:43 +08:00
2022-10-21 18:36:03 +08:00
private AssetsPackage ( )
2022-09-28 14:39:58 +08:00
{
2022-09-29 18:40:43 +08:00
}
2022-10-14 11:49:32 +08:00
internal AssetsPackage ( string packageName )
2022-09-29 18:40:43 +08:00
{
PackageName = packageName ;
}
2022-09-28 14:39:58 +08:00
2022-09-29 18:40:43 +08:00
/// <summary>
/// 更新资源包裹
/// </summary>
internal void UpdatePackage ( )
{
if ( _assetSystemImpl ! = null )
_assetSystemImpl . Update ( ) ;
}
2022-09-28 14:39:58 +08:00
2022-09-29 18:40:43 +08:00
/// <summary>
/// 销毁资源包裹
/// </summary>
internal void DestroyPackage ( )
{
2022-09-28 14:39:58 +08:00
if ( _isInitialize )
{
2022-09-29 18:40:43 +08:00
_isInitialize = false ;
_initializeError = string . Empty ;
_initializeStatus = EOperationStatus . None ;
2022-09-28 14:39:58 +08:00
2022-09-29 18:40:43 +08:00
_bundleServices = null ;
_editorSimulateModeImpl = null ;
_offlinePlayModeImpl = null ;
_hostPlayModeImpl = null ;
2022-09-28 14:39:58 +08:00
2022-09-29 18:40:43 +08:00
if ( _assetSystemImpl ! = null )
{
_assetSystemImpl . DestroyAll ( ) ;
_assetSystemImpl = null ;
}
2022-09-28 14:39:58 +08:00
}
2022-09-29 18:40:43 +08:00
}
2022-09-28 14:39:58 +08:00
2022-09-29 18:40:43 +08:00
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync ( InitializeParameters parameters )
{
// 检测初始化参数合法性
CheckInitializeParameters ( parameters ) ;
2022-09-28 14:39:58 +08:00
// 初始化资源系统
InitializationOperation initializeOperation ;
2022-09-29 18:40:43 +08:00
_assetSystemImpl = new AssetSystemImpl ( ) ;
2022-09-28 14:39:58 +08:00
if ( _playMode = = EPlayMode . EditorSimulateMode )
{
_editorSimulateModeImpl = new EditorSimulateModeImpl ( ) ;
_bundleServices = _editorSimulateModeImpl ;
2022-09-29 18:40:43 +08:00
_assetSystemImpl . Initialize ( true , parameters . AssetLoadingMaxNumber , parameters . DecryptionServices , _bundleServices ) ;
var initializeParameters = parameters as EditorSimulateModeParameters ;
2022-09-28 14:39:58 +08:00
initializeOperation = _editorSimulateModeImpl . InitializeAsync (
2022-09-29 18:40:43 +08:00
initializeParameters . LocationToLower ,
initializeParameters . SimulatePatchManifestPath ) ;
2022-09-28 14:39:58 +08:00
}
else if ( _playMode = = EPlayMode . OfflinePlayMode )
{
_offlinePlayModeImpl = new OfflinePlayModeImpl ( ) ;
_bundleServices = _offlinePlayModeImpl ;
2022-09-29 18:40:43 +08:00
_assetSystemImpl . Initialize ( false , parameters . AssetLoadingMaxNumber , parameters . DecryptionServices , _bundleServices ) ;
var initializeParameters = parameters as OfflinePlayModeParameters ;
2022-09-28 14:39:58 +08:00
initializeOperation = _offlinePlayModeImpl . InitializeAsync (
2022-09-29 18:40:43 +08:00
initializeParameters . LocationToLower ,
PackageName ) ;
2022-09-28 14:39:58 +08:00
}
else if ( _playMode = = EPlayMode . HostPlayMode )
{
_hostPlayModeImpl = new HostPlayModeImpl ( ) ;
_bundleServices = _hostPlayModeImpl ;
2022-09-29 18:40:43 +08:00
_assetSystemImpl . Initialize ( false , parameters . AssetLoadingMaxNumber , parameters . DecryptionServices , _bundleServices ) ;
var initializeParameters = parameters as HostPlayModeParameters ;
2022-09-28 14:39:58 +08:00
initializeOperation = _hostPlayModeImpl . InitializeAsync (
2022-09-29 18:40:43 +08:00
initializeParameters . LocationToLower ,
initializeParameters . DefaultHostServer ,
initializeParameters . FallbackHostServer ,
initializeParameters . QueryServices ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
// 监听初始化结果
2022-10-22 15:37:53 +08:00
_isInitialize = true ;
2022-09-28 14:39:58 +08:00
initializeOperation . Completed + = InitializeOperation_Completed ;
return initializeOperation ;
}
2022-09-29 18:40:43 +08:00
private void CheckInitializeParameters ( InitializeParameters parameters )
{
if ( _isInitialize )
2022-10-14 11:49:32 +08:00
throw new Exception ( $"{nameof(AssetsPackage)} is initialized yet." ) ;
2022-09-29 18:40:43 +08:00
if ( parameters = = null )
2022-10-14 11:49:32 +08:00
throw new Exception ( $"{nameof(AssetsPackage)} create parameters is null." ) ;
2022-09-29 18:40:43 +08:00
#if ! UNITY_EDITOR
if ( parameters is EditorSimulateModeParameters )
throw new Exception ( $"Editor simulate mode only support unity editor." ) ;
#endif
2022-10-18 12:07:33 +08:00
if ( parameters is EditorSimulateModeParameters )
2022-09-29 18:40:43 +08:00
{
var editorSimulateModeParameters = parameters as EditorSimulateModeParameters ;
if ( string . IsNullOrEmpty ( editorSimulateModeParameters . SimulatePatchManifestPath ) )
2022-10-19 19:30:50 +08:00
throw new Exception ( $"{nameof(editorSimulateModeParameters.SimulatePatchManifestPath)} is null or empty." ) ;
2022-09-29 18:40:43 +08:00
}
if ( parameters is HostPlayModeParameters )
{
var hostPlayModeParameters = parameters as HostPlayModeParameters ;
if ( string . IsNullOrEmpty ( hostPlayModeParameters . DefaultHostServer ) )
throw new Exception ( $"${hostPlayModeParameters.DefaultHostServer} is null or empty." ) ;
if ( string . IsNullOrEmpty ( hostPlayModeParameters . FallbackHostServer ) )
throw new Exception ( $"${hostPlayModeParameters.FallbackHostServer} is null or empty." ) ;
if ( hostPlayModeParameters . QueryServices = = null )
throw new Exception ( $"{nameof(IQueryServices)} is null." ) ;
}
// 鉴定运行模式
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 . AssetLoadingMaxNumber < 1 )
{
parameters . AssetLoadingMaxNumber = 1 ;
YooLogger . Warning ( $"{nameof(parameters.AssetLoadingMaxNumber)} minimum value is 1" ) ;
}
}
2022-09-28 14:39:58 +08:00
private void InitializeOperation_Completed ( AsyncOperationBase op )
{
_initializeStatus = op . Status ;
_initializeError = op . Error ;
}
/// <summary>
/// 向网络端请求静态资源版本
/// </summary>
/// <param name="timeout">超时时间( 默认值: 60秒) </param>
2022-09-29 18:40:43 +08:00
public UpdateStaticVersionOperation UpdateStaticVersionAsync ( int timeout = 60 )
2022-09-28 14:39:58 +08:00
{
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 )
{
2022-09-29 18:40:43 +08:00
return _hostPlayModeImpl . UpdateStaticVersionAsync ( PackageName , timeout ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
/// <summary>
/// 向网络端请求并更新补丁清单
/// </summary>
2022-10-26 21:02:25 +08:00
/// <param name="packageVersion">更新的包裹版本</param>
2022-09-28 14:39:58 +08:00
/// <param name="timeout">超时时间( 默认值: 60秒) </param>
2022-10-26 21:02:25 +08:00
public UpdateManifestOperation UpdateManifestAsync ( string packageVersion , int timeout = 60 )
2022-09-28 14:39:58 +08:00
{
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 )
{
2022-10-26 21:02:25 +08:00
return _hostPlayModeImpl . UpdatePatchManifestAsync ( PackageName , packageVersion , timeout ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
/// <summary>
/// 弱联网情况下加载补丁清单
/// 注意:当指定版本内容验证失败后会返回失败。
/// </summary>
2022-10-26 21:02:25 +08:00
/// <param name="packageVersion">指定的包裹版本</param>
public UpdateManifestOperation WeaklyUpdateManifestAsync ( string packageVersion )
2022-09-28 14:39:58 +08:00
{
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 )
{
2022-10-26 21:02:25 +08:00
return _hostPlayModeImpl . WeaklyUpdatePatchManifestAsync ( PackageName , packageVersion ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
2022-10-17 16:04:47 +08:00
/// <summary>
2022-10-26 21:02:25 +08:00
/// 获取包裹的版本信息
2022-10-17 16:04:47 +08:00
/// </summary>
2022-10-26 21:02:25 +08:00
public string GetPackageVersion ( )
2022-10-17 16:04:47 +08:00
{
DebugCheckInitialize ( ) ;
if ( _playMode = = EPlayMode . EditorSimulateMode )
{
2022-10-26 21:02:25 +08:00
return _editorSimulateModeImpl . GetPackageVersion ( ) ;
2022-10-17 16:04:47 +08:00
}
else if ( _playMode = = EPlayMode . OfflinePlayMode )
{
2022-10-26 21:02:25 +08:00
return _offlinePlayModeImpl . GetPackageVersion ( ) ;
2022-10-17 16:04:47 +08:00
}
else if ( _playMode = = EPlayMode . HostPlayMode )
{
2022-10-26 21:02:25 +08:00
return _hostPlayModeImpl . GetPackageVersion ( ) ;
2022-10-17 16:04:47 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
2022-09-28 14:39:58 +08:00
/// <summary>
/// 资源回收(卸载引用计数为零的资源)
/// </summary>
public void UnloadUnusedAssets ( )
{
2022-10-22 15:37:53 +08:00
DebugCheckInitialize ( ) ;
_assetSystemImpl . Update ( ) ;
_assetSystemImpl . UnloadUnusedAssets ( ) ;
2022-09-28 14:39:58 +08:00
}
/// <summary>
/// 强制回收所有资源
/// </summary>
public void ForceUnloadAllAssets ( )
{
2022-10-22 15:37:53 +08:00
DebugCheckInitialize ( ) ;
_assetSystemImpl . ForceUnloadAllAssets ( ) ;
2022-09-28 14:39:58 +08:00
}
#region 资 源 信 息
/// <summary>
/// 是否需要从远端更新下载
/// </summary>
/// <param name="location">资源的定位地址</param>
public bool IsNeedDownloadFromRemote ( string location )
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , null ) ;
if ( assetInfo . IsInvalid )
2022-10-21 18:36:03 +08:00
{
YooLogger . Warning ( assetInfo . Error ) ;
2022-09-28 14:39:58 +08:00
return false ;
2022-10-21 18:36:03 +08:00
}
2022-09-28 14:39:58 +08:00
BundleInfo bundleInfo = _bundleServices . GetBundleInfo ( assetInfo ) ;
if ( bundleInfo . LoadMode = = BundleInfo . ELoadMode . LoadFromRemote )
return true ;
else
return false ;
}
/// <summary>
/// 是否需要从远端更新下载
/// </summary>
/// <param name="location">资源的定位地址</param>
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 ;
}
/// <summary>
/// 获取资源信息列表
/// </summary>
/// <param name="tag">资源标签</param>
public AssetInfo [ ] GetAssetInfos ( string tag )
{
DebugCheckInitialize ( ) ;
string [ ] tags = new string [ ] { tag } ;
return _bundleServices . GetAssetInfos ( tags ) ;
}
/// <summary>
/// 获取资源信息列表
/// </summary>
/// <param name="tags">资源标签列表</param>
public AssetInfo [ ] GetAssetInfos ( string [ ] tags )
{
DebugCheckInitialize ( ) ;
return _bundleServices . GetAssetInfos ( tags ) ;
}
/// <summary>
/// 获取资源信息
/// </summary>
/// <param name="location">资源的定位地址</param>
public AssetInfo GetAssetInfo ( string location )
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , null ) ;
return assetInfo ;
}
/// <summary>
2022-10-21 18:36:03 +08:00
/// 检查资源定位地址是否有效
2022-09-28 14:39:58 +08:00
/// </summary>
/// <param name="location">资源的定位地址</param>
2022-10-21 18:36:03 +08:00
public bool CheckLocationValid ( string location )
2022-09-28 14:39:58 +08:00
{
DebugCheckInitialize ( ) ;
2022-10-21 18:36:03 +08:00
string assetPath = _bundleServices . TryMappingToAssetPath ( location ) ;
return string . IsNullOrEmpty ( assetPath ) = = false ;
2022-09-28 14:39:58 +08:00
}
#endregion
#region 原 生 文 件
/// <summary>
/// 异步获取原生文件
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="copyPath">拷贝路径</param>
public RawFileOperation GetRawFileAsync ( string location , string copyPath = null )
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , null ) ;
return GetRawFileInternal ( assetInfo , copyPath ) ;
}
/// <summary>
/// 异步获取原生文件
/// </summary>
/// <param name="assetInfo">资源信息</param>
/// <param name="copyPath">拷贝路径</param>
public RawFileOperation GetRawFileAsync ( AssetInfo assetInfo , string copyPath = null )
{
DebugCheckInitialize ( ) ;
return GetRawFileInternal ( assetInfo , copyPath ) ;
}
private RawFileOperation GetRawFileInternal ( AssetInfo assetInfo , string copyPath )
{
if ( assetInfo . IsInvalid )
{
2022-10-21 18:36:03 +08:00
YooLogger . Error ( $"Failed to get raw file. {assetInfo.Error}" ) ;
2022-09-28 14:39:58 +08:00
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 场 景 加 载
/// <summary>
/// 异步加载场景
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="activateOnLoad">加载完毕时是否主动激活</param>
/// <param name="priority">优先级</param>
public SceneOperationHandle LoadSceneAsync ( string location , LoadSceneMode sceneMode = LoadSceneMode . Single , bool activateOnLoad = true , int priority = 100 )
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , null ) ;
2022-09-29 18:40:43 +08:00
var handle = _assetSystemImpl . LoadSceneAsync ( assetInfo , sceneMode , activateOnLoad , priority ) ;
2022-09-28 14:39:58 +08:00
return handle ;
}
/// <summary>
/// 异步加载场景
/// </summary>
/// <param name="assetInfo">场景的资源信息</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="activateOnLoad">加载完毕时是否主动激活</param>
/// <param name="priority">优先级</param>
public SceneOperationHandle LoadSceneAsync ( AssetInfo assetInfo , LoadSceneMode sceneMode = LoadSceneMode . Single , bool activateOnLoad = true , int priority = 100 )
{
DebugCheckInitialize ( ) ;
2022-09-29 18:40:43 +08:00
var handle = _assetSystemImpl . LoadSceneAsync ( assetInfo , sceneMode , activateOnLoad , priority ) ;
2022-09-28 14:39:58 +08:00
return handle ;
}
#endregion
#region 资 源 加 载
/// <summary>
/// 同步加载资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public AssetOperationHandle LoadAssetSync ( AssetInfo assetInfo )
{
DebugCheckInitialize ( ) ;
return LoadAssetInternal ( assetInfo , true ) ;
}
/// <summary>
/// 同步加载资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public AssetOperationHandle LoadAssetSync < TObject > ( string location ) where TObject : UnityEngine . Object
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , typeof ( TObject ) ) ;
return LoadAssetInternal ( assetInfo , true ) ;
}
/// <summary>
/// 同步加载资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">资源类型</param>
public AssetOperationHandle LoadAssetSync ( string location , System . Type type )
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , type ) ;
return LoadAssetInternal ( assetInfo , true ) ;
}
/// <summary>
/// 异步加载资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public AssetOperationHandle LoadAssetAsync ( AssetInfo assetInfo )
{
DebugCheckInitialize ( ) ;
return LoadAssetInternal ( assetInfo , false ) ;
}
/// <summary>
/// 异步加载资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public AssetOperationHandle LoadAssetAsync < TObject > ( string location ) where TObject : UnityEngine . Object
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , typeof ( TObject ) ) ;
return LoadAssetInternal ( assetInfo , false ) ;
}
/// <summary>
/// 异步加载资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">资源类型</param>
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
2022-10-21 18:36:03 +08:00
if ( assetInfo . IsInvalid = = false )
2022-09-28 14:39:58 +08:00
{
2022-10-21 18:36:03 +08:00
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 < AssetOperationHandle > ( ) ;
}
2022-09-28 14:39:58 +08:00
}
#endif
2022-09-29 18:40:43 +08:00
var handle = _assetSystemImpl . LoadAssetAsync ( assetInfo ) ;
2022-09-28 14:39:58 +08:00
if ( waitForAsyncComplete )
handle . WaitForAsyncComplete ( ) ;
return handle ;
}
#endregion
#region 资 源 加 载
/// <summary>
/// 同步加载子资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public SubAssetsOperationHandle LoadSubAssetsSync ( AssetInfo assetInfo )
{
DebugCheckInitialize ( ) ;
return LoadSubAssetsInternal ( assetInfo , true ) ;
}
/// <summary>
/// 同步加载子资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public SubAssetsOperationHandle LoadSubAssetsSync < TObject > ( string location ) where TObject : UnityEngine . Object
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , typeof ( TObject ) ) ;
return LoadSubAssetsInternal ( assetInfo , true ) ;
}
/// <summary>
/// 同步加载子资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public SubAssetsOperationHandle LoadSubAssetsSync ( string location , System . Type type )
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , type ) ;
return LoadSubAssetsInternal ( assetInfo , true ) ;
}
/// <summary>
/// 异步加载子资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public SubAssetsOperationHandle LoadSubAssetsAsync ( AssetInfo assetInfo )
{
DebugCheckInitialize ( ) ;
return LoadSubAssetsInternal ( assetInfo , false ) ;
}
/// <summary>
/// 异步加载子资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public SubAssetsOperationHandle LoadSubAssetsAsync < TObject > ( string location ) where TObject : UnityEngine . Object
{
DebugCheckInitialize ( ) ;
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , typeof ( TObject ) ) ;
return LoadSubAssetsInternal ( assetInfo , false ) ;
}
/// <summary>
/// 异步加载子资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
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
2022-10-21 18:36:03 +08:00
if ( assetInfo . IsInvalid = = false )
2022-09-28 14:39:58 +08:00
{
2022-10-21 18:36:03 +08:00
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 < SubAssetsOperationHandle > ( ) ;
}
2022-09-28 14:39:58 +08:00
}
#endif
2022-09-29 18:40:43 +08:00
var handle = _assetSystemImpl . LoadSubAssetsAsync ( assetInfo ) ;
2022-09-28 14:39:58 +08:00
if ( waitForAsyncComplete )
handle . WaitForAsyncComplete ( ) ;
return handle ;
}
#endregion
#region 资 源 下 载
/// <summary>
/// 创建补丁下载器,用于下载更新资源标签指定的资源包文件
/// </summary>
/// <param name="tag">资源标签</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
2022-10-17 14:43:13 +08:00
/// <param name="timeout">超时时间</param>
public PatchDownloaderOperation CreatePatchDownloader ( string tag , int downloadingMaxNumber , int failedTryAgain , int timeout = 60 )
2022-09-28 14:39:58 +08:00
{
DebugCheckInitialize ( ) ;
2022-10-17 14:43:13 +08:00
return CreatePatchDownloader ( new string [ ] { tag } , downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
}
/// <summary>
/// 创建补丁下载器,用于下载更新资源标签指定的资源包文件
/// </summary>
/// <param name="tags">资源标签列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
2022-10-17 14:43:13 +08:00
/// <param name="timeout">超时时间</param>
public PatchDownloaderOperation CreatePatchDownloader ( string [ ] tags , int downloadingMaxNumber , int failedTryAgain , int timeout = 60 )
2022-09-28 14:39:58 +08:00
{
DebugCheckInitialize ( ) ;
if ( _playMode = = EPlayMode . EditorSimulateMode | | _playMode = = EPlayMode . OfflinePlayMode )
{
List < BundleInfo > downloadList = new List < BundleInfo > ( ) ;
2022-10-17 14:43:13 +08:00
var operation = new PatchDownloaderOperation ( downloadList , downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
return operation ;
}
else if ( _playMode = = EPlayMode . HostPlayMode )
{
2022-10-17 14:43:13 +08:00
return _hostPlayModeImpl . CreatePatchDownloaderByTags ( tags , downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
/// <summary>
/// 创建补丁下载器,用于下载更新当前资源版本所有的资源包文件
/// </summary>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
2022-10-17 14:43:13 +08:00
/// <param name="timeout">超时时间</param>
public PatchDownloaderOperation CreatePatchDownloader ( int downloadingMaxNumber , int failedTryAgain , int timeout = 60 )
2022-09-28 14:39:58 +08:00
{
DebugCheckInitialize ( ) ;
if ( _playMode = = EPlayMode . EditorSimulateMode | | _playMode = = EPlayMode . OfflinePlayMode )
{
List < BundleInfo > downloadList = new List < BundleInfo > ( ) ;
2022-10-17 14:43:13 +08:00
var operation = new PatchDownloaderOperation ( downloadList , downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
return operation ;
}
else if ( _playMode = = EPlayMode . HostPlayMode )
{
2022-10-17 14:43:13 +08:00
return _hostPlayModeImpl . CreatePatchDownloaderByAll ( downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
/// <summary>
/// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件
/// </summary>
/// <param name="locations">资源定位列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
2022-10-17 14:43:13 +08:00
/// <param name="timeout">超时时间</param>
public PatchDownloaderOperation CreateBundleDownloader ( string [ ] locations , int downloadingMaxNumber , int failedTryAgain , int timeout = 60 )
2022-09-28 14:39:58 +08:00
{
DebugCheckInitialize ( ) ;
if ( _playMode = = EPlayMode . EditorSimulateMode | | _playMode = = EPlayMode . OfflinePlayMode )
{
List < BundleInfo > downloadList = new List < BundleInfo > ( ) ;
2022-10-17 14:43:13 +08:00
var operation = new PatchDownloaderOperation ( downloadList , downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
return operation ;
}
else if ( _playMode = = EPlayMode . HostPlayMode )
{
List < AssetInfo > assetInfos = new List < AssetInfo > ( locations . Length ) ;
foreach ( var location in locations )
{
AssetInfo assetInfo = ConvertLocationToAssetInfo ( location , null ) ;
assetInfos . Add ( assetInfo ) ;
}
2022-10-17 14:43:13 +08:00
return _hostPlayModeImpl . CreatePatchDownloaderByPaths ( assetInfos . ToArray ( ) , downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
/// <summary>
/// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件
/// </summary>
/// <param name="assetInfos">资源信息列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
2022-10-17 14:43:13 +08:00
/// <param name="timeout">超时时间</param>
public PatchDownloaderOperation CreateBundleDownloader ( AssetInfo [ ] assetInfos , int downloadingMaxNumber , int failedTryAgain , int timeout = 60 )
2022-09-28 14:39:58 +08:00
{
DebugCheckInitialize ( ) ;
if ( _playMode = = EPlayMode . EditorSimulateMode | | _playMode = = EPlayMode . OfflinePlayMode )
{
List < BundleInfo > downloadList = new List < BundleInfo > ( ) ;
2022-10-17 14:43:13 +08:00
var operation = new PatchDownloaderOperation ( downloadList , downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
return operation ;
}
else if ( _playMode = = EPlayMode . HostPlayMode )
{
2022-10-17 14:43:13 +08:00
return _hostPlayModeImpl . CreatePatchDownloaderByPaths ( assetInfos , downloadingMaxNumber , failedTryAgain , timeout ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
#endregion
#region 资 源 解 压
/// <summary>
/// 创建补丁解压器
/// </summary>
/// <param name="tag">资源标签</param>
/// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
/// <param name="failedTryAgain">解压失败的重试次数</param>
public PatchUnpackerOperation CreatePatchUnpacker ( string tag , int unpackingMaxNumber , int failedTryAgain )
{
DebugCheckInitialize ( ) ;
return CreatePatchUnpacker ( new string [ ] { tag } , unpackingMaxNumber , failedTryAgain ) ;
}
/// <summary>
/// 创建补丁解压器
/// </summary>
/// <param name="tags">资源标签列表</param>
/// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
/// <param name="failedTryAgain">解压失败的重试次数</param>
public PatchUnpackerOperation CreatePatchUnpacker ( string [ ] tags , int unpackingMaxNumber , int failedTryAgain )
{
DebugCheckInitialize ( ) ;
if ( _playMode = = EPlayMode . EditorSimulateMode )
{
List < BundleInfo > downloadList = new List < BundleInfo > ( ) ;
2022-10-17 14:43:13 +08:00
var operation = new PatchUnpackerOperation ( downloadList , unpackingMaxNumber , failedTryAgain , int . MaxValue ) ;
2022-09-28 14:39:58 +08:00
return operation ;
}
else if ( _playMode = = EPlayMode . OfflinePlayMode )
{
List < BundleInfo > downloadList = new List < BundleInfo > ( ) ;
2022-10-17 14:43:13 +08:00
var operation = new PatchUnpackerOperation ( downloadList , unpackingMaxNumber , failedTryAgain , int . MaxValue ) ;
2022-09-28 14:39:58 +08:00
return operation ;
}
else if ( _playMode = = EPlayMode . HostPlayMode )
{
2022-10-17 14:43:13 +08:00
return _hostPlayModeImpl . CreatePatchUnpackerByTags ( tags , unpackingMaxNumber , failedTryAgain , int . MaxValue ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
/// <summary>
/// 创建补丁解压器
/// </summary>
/// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
/// <param name="failedTryAgain">解压失败的重试次数</param>
public PatchUnpackerOperation CreatePatchUnpacker ( int unpackingMaxNumber , int failedTryAgain )
{
DebugCheckInitialize ( ) ;
if ( _playMode = = EPlayMode . EditorSimulateMode )
{
List < BundleInfo > downloadList = new List < BundleInfo > ( ) ;
2022-10-17 14:43:13 +08:00
var operation = new PatchUnpackerOperation ( downloadList , unpackingMaxNumber , failedTryAgain , int . MaxValue ) ;
2022-09-28 14:39:58 +08:00
return operation ;
}
else if ( _playMode = = EPlayMode . OfflinePlayMode )
{
List < BundleInfo > downloadList = new List < BundleInfo > ( ) ;
2022-10-17 14:43:13 +08:00
var operation = new PatchUnpackerOperation ( downloadList , unpackingMaxNumber , failedTryAgain , int . MaxValue ) ;
2022-09-28 14:39:58 +08:00
return operation ;
}
else if ( _playMode = = EPlayMode . HostPlayMode )
{
2022-10-17 14:43:13 +08:00
return _hostPlayModeImpl . CreatePatchUnpackerByAll ( unpackingMaxNumber , failedTryAgain , int . MaxValue ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
#endregion
#region 包 裹 更 新
/// <summary>
/// 创建资源包裹下载器,用于下载更新指定资源版本所有的资源包文件
/// </summary>
2022-10-26 21:02:25 +08:00
/// <param name="packageVersion">指定更新的包裹版本</param>
2022-09-28 14:39:58 +08:00
/// <param name="timeout">超时时间</param>
2022-10-26 21:02:25 +08:00
public UpdatePackageOperation UpdatePackageAsync ( string packageVersion , int timeout = 60 )
2022-09-28 14:39:58 +08:00
{
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 )
{
2022-10-26 21:02:25 +08:00
return _hostPlayModeImpl . UpdatePackageAsync ( PackageName , packageVersion , timeout ) ;
2022-09-28 14:39:58 +08:00
}
else
{
throw new NotImplementedException ( ) ;
}
}
#endregion
#region 内 部 方 法
2022-10-18 11:56:05 +08:00
/// <summary>
/// 是否包含资源文件
/// </summary>
internal bool IsIncludeBundleFile ( string fileName )
{
2022-10-18 12:07:33 +08:00
// NOTE : 编辑器模拟模式下始终返回TRUE
if ( _playMode = = EPlayMode . EditorSimulateMode )
return true ;
2022-10-18 11:56:05 +08:00
return _bundleServices . IsIncludeBundleFile ( fileName ) ;
}
2022-09-28 14:39:58 +08:00
#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 ( )
{
2022-09-29 18:40:43 +08:00
var loadedBundleInfos = _assetSystemImpl . GetLoadedBundleInfos ( ) ;
2022-09-28 14:39:58 +08:00
if ( loadedBundleInfos . Count > 0 )
{
YooLogger . Warning ( $"Found loaded bundle before update manifest ! Recommended to call the {nameof(ForceUnloadAllAssets)} method to release loaded bundle !" ) ;
}
}
#endregion
2022-09-29 18:40:43 +08:00
#region 调 试 信 息
2022-10-22 15:37:53 +08:00
internal DebugPackageData GetDebugPackageData ( )
2022-09-29 18:40:43 +08:00
{
2022-10-22 15:37:53 +08:00
DebugPackageData data = new DebugPackageData ( ) ;
data . PackageName = PackageName ;
data . ProviderInfos = _assetSystemImpl . GetDebugReportInfos ( ) ;
return data ;
2022-09-29 18:40:43 +08:00
}
#endregion
2022-09-28 14:39:58 +08:00
#region 私 有 方 法
/// <summary>
/// 资源定位地址转换为资源信息类,失败时内部会发出错误日志。
/// </summary>
/// <returns>如果转换失败会返回一个无效的资源信息类</returns>
private AssetInfo ConvertLocationToAssetInfo ( string location , System . Type assetType )
{
DebugCheckLocation ( location ) ;
2022-10-21 18:36:03 +08:00
string assetPath = _bundleServices . MappingToAssetPath ( location ) ;
2022-09-28 14:39:58 +08:00
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}" ;
AssetInfo assetInfo = new AssetInfo ( error ) ;
return assetInfo ;
}
}
#endregion
}
}