mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
909 lines
31 KiB
C#
909 lines
31 KiB
C#
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using YooAsset;
|
|
|
|
namespace TEngine
|
|
{
|
|
/// <summary>
|
|
/// 资源管理模块。
|
|
/// </summary>
|
|
[UpdateModule]
|
|
internal partial class ResourceManager : ModuleImp, IResourceManager
|
|
{
|
|
#region Propreties
|
|
|
|
/// <summary>
|
|
/// 资源包名称。
|
|
/// </summary>
|
|
public string PackageName { get; set; } = "DefaultPackage";
|
|
|
|
/// <summary>
|
|
/// 默认资源包。
|
|
/// </summary>
|
|
public ResourcePackage DefaultPackage { private set; get; }
|
|
|
|
/// <summary>
|
|
/// 获取当前资源适用的游戏版本号。
|
|
/// </summary>
|
|
// ReSharper disable once ConvertToAutoProperty
|
|
public string ApplicableGameVersion => _applicableGameVersion;
|
|
|
|
private string _applicableGameVersion;
|
|
|
|
/// <summary>
|
|
/// 获取当前内部资源版本号。
|
|
/// </summary>
|
|
// ReSharper disable once ConvertToAutoProperty
|
|
public int InternalResourceVersion => _internalResourceVersion;
|
|
|
|
private int _internalResourceVersion;
|
|
|
|
/// <summary>
|
|
/// 同时下载的最大数目。
|
|
/// </summary>
|
|
public int DownloadingMaxNum { get; set; }
|
|
|
|
/// <summary>
|
|
/// 失败重试最大数目。
|
|
/// </summary>
|
|
public int FailedTryAgain { get; set; }
|
|
|
|
/// <summary>
|
|
/// 获取资源只读区路径。
|
|
/// </summary>
|
|
public string ReadOnlyPath => _readOnlyPath;
|
|
|
|
private string _readOnlyPath;
|
|
|
|
/// <summary>
|
|
/// 获取资源读写区路径。
|
|
/// </summary>
|
|
public string ReadWritePath => _readWritePath;
|
|
|
|
private string _readWritePath;
|
|
|
|
/// <summary>
|
|
/// 资源系统运行模式。
|
|
/// </summary>
|
|
public EPlayMode PlayMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// 下载文件校验等级。
|
|
/// </summary>
|
|
public EVerifyLevel VerifyLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)。
|
|
/// </summary>
|
|
public long Milliseconds { get; set; }
|
|
|
|
/// <summary>
|
|
/// 获取游戏框架模块优先级。
|
|
/// </summary>
|
|
/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>
|
|
internal override int Priority => 4;
|
|
|
|
/// <summary>
|
|
/// 资源缓存表容量。
|
|
/// </summary>
|
|
public int ARCTableCapacity { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region 生命周期
|
|
|
|
internal override void Update(float elapseSeconds, float realElapseSeconds)
|
|
{
|
|
ResourcePool.Update();
|
|
}
|
|
|
|
internal override void Shutdown()
|
|
{
|
|
ReleaseAllHandle();
|
|
YooAssets.Destroy();
|
|
ResourcePool.Destroy();
|
|
}
|
|
|
|
private void ReleaseAllHandle()
|
|
{
|
|
var iter = _releaseMaps.Values.GetEnumerator();
|
|
while (iter.MoveNext())
|
|
{
|
|
AssetOperationHandle handle = iter.Current;
|
|
if (handle != null)
|
|
{
|
|
handle.Dispose();
|
|
handle = null;
|
|
}
|
|
}
|
|
|
|
iter.Dispose();
|
|
_releaseMaps.Clear();
|
|
|
|
iter = _operationHandlesMaps.Values.GetEnumerator();
|
|
while (iter.MoveNext())
|
|
{
|
|
AssetOperationHandle handle = iter.Current;
|
|
if (handle != null)
|
|
{
|
|
handle.Dispose();
|
|
handle = null;
|
|
}
|
|
}
|
|
|
|
iter.Dispose();
|
|
_operationHandlesMaps.Clear();
|
|
_arcCacheTable = new ArcCacheTable<string, AssetOperationHandle>(ARCTableCapacity, OnAddAsset, OnRemoveAsset);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 设置接口
|
|
|
|
/// <summary>
|
|
/// 设置资源只读区路径。
|
|
/// </summary>
|
|
/// <param name="readOnlyPath">资源只读区路径。</param>
|
|
public void SetReadOnlyPath(string readOnlyPath)
|
|
{
|
|
if (string.IsNullOrEmpty(readOnlyPath))
|
|
{
|
|
throw new GameFrameworkException("Read-only path is invalid.");
|
|
}
|
|
|
|
_readOnlyPath = readOnlyPath;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置资源读写区路径。
|
|
/// </summary>
|
|
/// <param name="readWritePath">资源读写区路径。</param>
|
|
public void SetReadWritePath(string readWritePath)
|
|
{
|
|
if (string.IsNullOrEmpty(readWritePath))
|
|
{
|
|
throw new GameFrameworkException("Read-write path is invalid.");
|
|
}
|
|
|
|
_readWritePath = readWritePath;
|
|
}
|
|
|
|
#endregion
|
|
|
|
private Dictionary<string, AssetOperationHandle> _releaseMaps;
|
|
|
|
private Dictionary<string, AssetOperationHandle> _operationHandlesMaps;
|
|
|
|
private ArcCacheTable<string, AssetOperationHandle> _arcCacheTable;
|
|
|
|
|
|
private void OnAddAsset(string location, AssetOperationHandle handle)
|
|
{
|
|
_operationHandlesMaps[location] = handle;
|
|
if (_releaseMaps.ContainsKey(location))
|
|
{
|
|
_releaseMaps.Remove(location);
|
|
}
|
|
}
|
|
|
|
private void OnRemoveAsset(string location, AssetOperationHandle handle)
|
|
{
|
|
if (_operationHandlesMaps.ContainsKey(location))
|
|
{
|
|
_operationHandlesMaps.Remove(location);
|
|
}
|
|
|
|
_releaseMaps[location] = handle;
|
|
GameModule.Resource.UnloadUnusedAssets(performGCCollect: false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 从缓存中获取同步资源句柄。
|
|
/// </summary>
|
|
/// <param name="location">资源定位地址。</param>
|
|
/// <typeparam name="T">资源类型。</typeparam>
|
|
/// <returns>资源句柄。</returns>
|
|
private AssetOperationHandle GetHandleSync<T>(string location) where T : Object
|
|
{
|
|
AssetOperationHandle handle = null;
|
|
// 尝试从从ARC缓存表取出对象。
|
|
handle = _arcCacheTable.GetCache(location);
|
|
|
|
if (handle == null)
|
|
{
|
|
handle = YooAssets.LoadAssetSync<T>(location);
|
|
}
|
|
|
|
// 对象推入ARC缓存表。
|
|
_arcCacheTable.PutCache(location, handle);
|
|
return handle;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 从缓存中获取异步资源句柄。
|
|
/// </summary>
|
|
/// <param name="location">资源定位地址。</param>
|
|
/// <typeparam name="T">资源类型。</typeparam>
|
|
/// <returns>资源句柄。</returns>
|
|
private AssetOperationHandle GetHandleAsync<T>(string location) where T : Object
|
|
{
|
|
AssetOperationHandle handle = null;
|
|
// 尝试从从ARC缓存表取出对象。
|
|
handle = _arcCacheTable.GetCache(location);
|
|
|
|
if (handle == null)
|
|
{
|
|
handle = YooAssets.LoadAssetAsync<T>(location);
|
|
}
|
|
|
|
// 对象推入ARC缓存表。
|
|
_arcCacheTable.PutCache(location, handle);
|
|
return handle;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化资源模块。
|
|
/// </summary>
|
|
public void Initialize()
|
|
{
|
|
// 初始化资源系统
|
|
YooAssets.Initialize(new AssetsLogger());
|
|
YooAssets.SetOperationSystemMaxTimeSlice(Milliseconds);
|
|
YooAssets.SetCacheSystemCachedFileVerifyLevel(VerifyLevel);
|
|
|
|
// 创建默认的资源包
|
|
string packageName = PackageName;
|
|
var defaultPackage = YooAssets.TryGetPackage(packageName);
|
|
if (defaultPackage == null)
|
|
{
|
|
defaultPackage = YooAssets.CreatePackage(packageName);
|
|
YooAssets.SetDefaultPackage(defaultPackage);
|
|
}
|
|
|
|
ResourcePool.Initialize(GameModule.Get<ResourceModule>().gameObject);
|
|
|
|
_releaseMaps ??= new Dictionary<string, AssetOperationHandle>(ARCTableCapacity);
|
|
_operationHandlesMaps ??= new Dictionary<string, AssetOperationHandle>(ARCTableCapacity);
|
|
_arcCacheTable ??= new ArcCacheTable<string, AssetOperationHandle>(ARCTableCapacity, OnAddAsset, OnRemoveAsset);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化资源包裹。
|
|
/// </summary>
|
|
/// <returns>初始化资源包裹操作句柄。</returns>
|
|
public InitializationOperation InitPackage()
|
|
{
|
|
// 创建默认的资源包
|
|
string packageName = PackageName;
|
|
var package = YooAssets.TryGetPackage(packageName);
|
|
if (package == null)
|
|
{
|
|
package = YooAssets.CreatePackage(packageName);
|
|
YooAssets.SetDefaultPackage(package);
|
|
}
|
|
|
|
DefaultPackage = package;
|
|
|
|
#if UNITY_EDITOR
|
|
//编辑器模式使用。
|
|
EPlayMode playMode = (EPlayMode)UnityEditor.EditorPrefs.GetInt("EditorResourceMode");
|
|
Log.Warning($"编辑器模式使用:{playMode}");
|
|
#else
|
|
//运行时使用。
|
|
EPlayMode playMode = PlayMode;
|
|
#endif
|
|
|
|
// 编辑器下的模拟模式
|
|
InitializationOperation initializationOperation = null;
|
|
if (playMode == EPlayMode.EditorSimulateMode)
|
|
{
|
|
var createParameters = new EditorSimulateModeParameters();
|
|
createParameters.SimulateManifestFilePath = EditorSimulateModeHelper.SimulateBuild(packageName);
|
|
initializationOperation = package.InitializeAsync(createParameters);
|
|
}
|
|
|
|
// 单机运行模式
|
|
if (playMode == EPlayMode.OfflinePlayMode)
|
|
{
|
|
var createParameters = new OfflinePlayModeParameters();
|
|
createParameters.DecryptionServices = new GameDecryptionServices();
|
|
initializationOperation = package.InitializeAsync(createParameters);
|
|
}
|
|
|
|
// 联机运行模式
|
|
if (playMode == EPlayMode.HostPlayMode)
|
|
{
|
|
var createParameters = new HostPlayModeParameters();
|
|
createParameters.DecryptionServices = new GameDecryptionServices();
|
|
createParameters.BuildinQueryServices = new BuiltinQueryServices();
|
|
createParameters.DeliveryQueryServices = new DefaultDeliveryQueryServices();
|
|
createParameters.RemoteServices = new RemoteServices();
|
|
initializationOperation = package.InitializeAsync(createParameters);
|
|
}
|
|
|
|
// WebGL运行模式
|
|
if (playMode == EPlayMode.WebPlayMode)
|
|
{
|
|
YooAssets.SetCacheSystemDisableCacheOnWebGL();
|
|
var createParameters = new WebPlayModeParameters();
|
|
createParameters.DecryptionServices = new GameDecryptionServices();
|
|
createParameters.BuildinQueryServices = new BuiltinQueryServices();
|
|
createParameters.RemoteServices = new RemoteServices();
|
|
initializationOperation = package.InitializeAsync(createParameters);
|
|
}
|
|
|
|
return initializationOperation;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 卸载资源。
|
|
/// </summary>
|
|
/// <param name="asset">要卸载的资源实例。</param>
|
|
/// <exception cref="GameFrameworkException">游戏框架异常类 - 未实现。</exception>
|
|
public void UnloadAsset(object asset)
|
|
{
|
|
throw new GameFrameworkException("System.NotImplementedException.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 资源回收(卸载引用计数为零的资源)。
|
|
/// </summary>
|
|
public void UnloadUnusedAssets()
|
|
{
|
|
var iter = _releaseMaps.Values.GetEnumerator();
|
|
while (iter.MoveNext())
|
|
{
|
|
AssetOperationHandle handle = iter.Current;
|
|
if (handle != null)
|
|
{
|
|
handle.Dispose();
|
|
handle = null;
|
|
}
|
|
}
|
|
|
|
iter.Dispose();
|
|
_releaseMaps.Clear();
|
|
|
|
if (DefaultPackage == null)
|
|
{
|
|
throw new GameFrameworkException("Package is invalid.");
|
|
}
|
|
|
|
DefaultPackage.UnloadUnusedAssets();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 强制回收所有资源。
|
|
/// </summary>
|
|
public void ForceUnloadAllAssets()
|
|
{
|
|
#if UNITY_WEBGL
|
|
return;
|
|
#else
|
|
if (DefaultPackage == null)
|
|
{
|
|
throw new GameFrameworkException("Package is invalid.");
|
|
}
|
|
|
|
DefaultPackage.ForceUnloadAllAssets();
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查资源是否存在。
|
|
/// </summary>
|
|
/// <param name="location">要检查资源的名称。</param>
|
|
/// <returns>检查资源是否存在的结果。</returns>
|
|
public HasAssetResult HasAsset(string location)
|
|
{
|
|
if (string.IsNullOrEmpty(location))
|
|
{
|
|
throw new GameFrameworkException("Asset name is invalid.");
|
|
}
|
|
|
|
AssetInfo assetInfo = YooAssets.GetAssetInfo(location);
|
|
|
|
if (!CheckLocationValid(location))
|
|
{
|
|
return HasAssetResult.Valid;
|
|
}
|
|
|
|
if (assetInfo == null)
|
|
{
|
|
return HasAssetResult.NotExist;
|
|
}
|
|
|
|
if (IsNeedDownloadFromRemote(assetInfo))
|
|
{
|
|
return HasAssetResult.AssetOnline;
|
|
}
|
|
|
|
return HasAssetResult.AssetOnDisk;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置默认的资源包。
|
|
/// </summary>
|
|
public void SetDefaultPackage(ResourcePackage package)
|
|
{
|
|
YooAssets.SetDefaultPackage(package);
|
|
DefaultPackage = package;
|
|
}
|
|
|
|
#region 资源信息
|
|
|
|
/// <summary>
|
|
/// 是否需要从远端更新下载。
|
|
/// </summary>
|
|
/// <param name="location">资源的定位地址</param>
|
|
public bool IsNeedDownloadFromRemote(string location)
|
|
{
|
|
return YooAssets.IsNeedDownloadFromRemote(location);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否需要从远端更新下载。
|
|
/// </summary>
|
|
/// <param name="assetInfo">资源信息。</param>
|
|
public bool IsNeedDownloadFromRemote(AssetInfo assetInfo)
|
|
{
|
|
return YooAssets.IsNeedDownloadFromRemote(assetInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取资源信息列表。
|
|
/// </summary>
|
|
/// <param name="tag">资源标签。</param>
|
|
/// <returns>资源信息列表。</returns>
|
|
public AssetInfo[] GetAssetInfos(string tag)
|
|
{
|
|
return YooAssets.GetAssetInfos(tag);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取资源信息列表。
|
|
/// </summary>
|
|
/// <param name="tags">资源标签列表。</param>
|
|
/// <returns>资源信息列表。</returns>
|
|
public AssetInfo[] GetAssetInfos(string[] tags)
|
|
{
|
|
return YooAssets.GetAssetInfos(tags);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取资源信息。
|
|
/// </summary>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
/// <returns>资源信息。</returns>
|
|
public AssetInfo GetAssetInfo(string location)
|
|
{
|
|
return YooAssets.GetAssetInfo(location);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查资源定位地址是否有效。
|
|
/// </summary>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
public bool CheckLocationValid(string location)
|
|
{
|
|
return YooAssets.CheckLocationValid(location);
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 同步加载资源。
|
|
/// </summary>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
/// <param name="needInstance">是否需要实例化。</param>
|
|
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
|
/// <returns>资源实例。</returns>
|
|
public T LoadAsset<T>(string location, bool needInstance = true) where T : Object
|
|
{
|
|
if (string.IsNullOrEmpty(location))
|
|
{
|
|
Log.Error("Asset name is invalid.");
|
|
return default;
|
|
}
|
|
|
|
AssetOperationHandle handle = GetHandleSync<T>(location);
|
|
|
|
if (typeof(T) == typeof(GameObject))
|
|
{
|
|
if (needInstance)
|
|
{
|
|
GameObject ret = handle.InstantiateSync();
|
|
return ret as T;
|
|
}
|
|
|
|
return handle.AssetObject as T;
|
|
}
|
|
else
|
|
{
|
|
T ret = handle.AssetObject as T;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步加载资源。
|
|
/// </summary>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
/// <param name="parent">父节点位置。</param>
|
|
/// <param name="needInstance">是否需要实例化。</param>
|
|
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
|
/// <returns>资源实例。</returns>
|
|
public T LoadAsset<T>(string location, Transform parent, bool needInstance = true) where T : Object
|
|
{
|
|
if (string.IsNullOrEmpty(location))
|
|
{
|
|
Log.Error("Asset name is invalid.");
|
|
return default;
|
|
}
|
|
|
|
AssetOperationHandle handle = GetHandleSync<T>(location);
|
|
|
|
if (typeof(T) == typeof(GameObject))
|
|
{
|
|
if (needInstance)
|
|
{
|
|
GameObject ret = handle.InstantiateSync();
|
|
return ret as T;
|
|
}
|
|
|
|
return handle.AssetObject as T;
|
|
}
|
|
else
|
|
{
|
|
T ret = handle.AssetObject as T;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步加载资源。
|
|
/// </summary>
|
|
/// <param name="handle">资源操作句柄。</param>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
|
/// <returns>资源实例。</returns>
|
|
public T LoadAsset<T>(string location, out AssetOperationHandle handle) where T : Object
|
|
{
|
|
handle = GetHandleSync<T>(location);
|
|
if (string.IsNullOrEmpty(location))
|
|
{
|
|
Log.Error("Asset name is invalid.");
|
|
return default;
|
|
}
|
|
|
|
if (typeof(T) == typeof(GameObject))
|
|
{
|
|
GameObject ret = handle.InstantiateSync();
|
|
return ret as T;
|
|
}
|
|
else
|
|
{
|
|
return handle.AssetObject as T;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步加载资源。
|
|
/// </summary>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
/// <param name="handle">资源操作句柄。</param>
|
|
/// <param name="parent">父节点位置。</param>
|
|
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
|
/// <returns>资源实例。</returns>
|
|
public T LoadAsset<T>(string location, Transform parent, out AssetOperationHandle handle) where T : Object
|
|
{
|
|
handle = GetHandleSync<T>(location);
|
|
|
|
if (string.IsNullOrEmpty(location))
|
|
{
|
|
Log.Error("Asset name is invalid.");
|
|
return default;
|
|
}
|
|
|
|
if (typeof(T) == typeof(GameObject))
|
|
{
|
|
GameObject ret = handle.InstantiateSync(parent);
|
|
return ret as T;
|
|
}
|
|
else
|
|
{
|
|
return handle.AssetObject as T;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步加载资源并获取句柄。
|
|
/// </summary>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
|
/// <returns>同步加载资源句柄。</returns>
|
|
public AssetOperationHandle LoadAssetGetOperation<T>(string location) where T : Object
|
|
{
|
|
return GetHandleSync<T>(location);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载资源并获取句柄。
|
|
/// </summary>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
/// <typeparam name="T">要加载资源的类型。</typeparam>
|
|
/// <returns>异步加载资源句柄。</returns>
|
|
public AssetOperationHandle LoadAssetAsyncHandle<T>(string location) where T : Object
|
|
{
|
|
return GetHandleAsync<T>(location);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步加载子资源对象
|
|
/// </summary>
|
|
/// <typeparam name="TObject">资源类型。</typeparam>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
public SubAssetsOperationHandle LoadSubAssetsSync<TObject>(string location) where TObject : Object
|
|
{
|
|
return YooAssets.LoadSubAssetsSync<TObject>(location: location);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载子资源对象
|
|
/// </summary>
|
|
/// <typeparam name="TObject">资源类型。</typeparam>
|
|
/// <param name="location">资源的定位地址。</param>
|
|
public SubAssetsOperationHandle LoadSubAssetsAsync<TObject>(string location) where TObject : Object
|
|
{
|
|
return YooAssets.LoadSubAssetsAsync<TObject>(location: location);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步加载子资源对象
|
|
/// </summary>
|
|
/// <param name="assetInfo">资源信息。</param>
|
|
public SubAssetsOperationHandle LoadSubAssetsSync(AssetInfo assetInfo)
|
|
{
|
|
return YooAssets.LoadSubAssetsSync(assetInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 通过Tag加载资源对象集合。
|
|
/// </summary>
|
|
/// <param name="assetTag">资源标识。</param>
|
|
/// <typeparam name="T">资源类型。</typeparam>
|
|
/// <returns>资源对象集合。</returns>
|
|
public async UniTask<List<T>> LoadAssetsByTagAsync<T>(string assetTag) where T : UnityEngine.Object
|
|
{
|
|
LoadAssetsByTagOperation<T> operation = new LoadAssetsByTagOperation<T>(assetTag);
|
|
YooAssets.StartOperation(operation);
|
|
await operation.ToUniTask();
|
|
List<T> assetObjects = operation.AssetObjects;
|
|
operation.ReleaseHandle();
|
|
return assetObjects;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载场景。
|
|
/// </summary>
|
|
/// <param name="location">场景的定位地址。</param>
|
|
/// <param name="sceneMode">场景加载模式。</param>
|
|
/// <param name="suspendLoad">加载完毕时是否主动挂起。</param>
|
|
/// <param name="priority">加载优先级。</param>
|
|
/// <returns>异步加载场景句柄。</returns>
|
|
public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false,
|
|
int priority = 100)
|
|
{
|
|
return YooAssets.LoadSceneAsync(location, sceneMode, suspendLoad, priority);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载场景。
|
|
/// </summary>
|
|
/// <param name="assetInfo">场景的资源信息。</param>
|
|
/// <param name="sceneMode">场景加载模式。</param>
|
|
/// <param name="suspendLoad">加载完毕时是否主动挂起。</param>
|
|
/// <param name="priority">加载优先级。</param>
|
|
/// <returns>异步加载场景句柄。</returns>
|
|
public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false,
|
|
int priority = 100)
|
|
{
|
|
return YooAssets.LoadSceneAsync(assetInfo, sceneMode, suspendLoad, priority);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 异步加载资源实例。
|
|
/// </summary>
|
|
/// <param name="location">要加载的实例名称。</param>
|
|
/// <param name="cancellationToken">取消操作Token。</param>
|
|
/// <param name="needInstance">是否需要实例化。</param>
|
|
/// <returns>资源实实例。</returns>
|
|
public async UniTask<T> LoadAssetAsync<T>(string location, CancellationToken cancellationToken = default, bool needInstance = true) where T : Object
|
|
{
|
|
AssetOperationHandle handle = LoadAssetAsyncHandle<T>(location);
|
|
|
|
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
|
|
|
|
if (cancelOrFailed)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (typeof(T) == typeof(GameObject))
|
|
{
|
|
if (needInstance)
|
|
{
|
|
GameObject ret = handle.InstantiateSync();
|
|
return ret as T;
|
|
}
|
|
|
|
return handle.AssetObject as T;
|
|
}
|
|
else
|
|
{
|
|
return handle.AssetObject as T;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载游戏物体。
|
|
/// </summary>
|
|
/// <param name="location">要加载的游戏物体名称。</param>
|
|
/// <param name="cancellationToken">取消操作Token。</param>
|
|
/// <returns>异步游戏物体实例。</returns>
|
|
public async UniTask<GameObject> LoadGameObjectAsync(string location, CancellationToken cancellationToken = default)
|
|
{
|
|
AssetOperationHandle handle = LoadAssetAsyncHandle<GameObject>(location);
|
|
|
|
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
|
|
|
|
if (cancelOrFailed)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
GameObject ret = handle.InstantiateSync();
|
|
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载游戏物体。
|
|
/// </summary>
|
|
/// <param name="location">资源定位地址。</param>
|
|
/// <param name="parent">父节点位置。</param>
|
|
/// <param name="cancellationToken">取消操作Token。</param>
|
|
/// <returns>异步游戏物体实例。</returns>
|
|
public async UniTask<GameObject> LoadGameObjectAsync(string location, Transform parent, CancellationToken cancellationToken = default)
|
|
{
|
|
GameObject gameObject = await LoadGameObjectAsync(location, cancellationToken);
|
|
if (parent != null)
|
|
{
|
|
gameObject.transform.SetParent(parent);
|
|
}
|
|
else
|
|
{
|
|
Log.Error("Set Parent Failed");
|
|
}
|
|
|
|
return gameObject;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载原生文件。
|
|
/// </summary>
|
|
/// <param name="location">资源定位地址。</param>
|
|
/// <param name="cancellationToken">取消操作Token。</param>
|
|
/// <returns>原生文件资源实例操作句柄。</returns>
|
|
/// <remarks>需要自行释放资源句柄(RawFileOperationHandle)。</remarks>
|
|
public async UniTask<RawFileOperationHandle> LoadRawAssetAsync(string location, CancellationToken cancellationToken = default)
|
|
{
|
|
RawFileOperationHandle handle = YooAssets.LoadRawFileAsync(location);
|
|
|
|
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
|
|
|
|
return cancelOrFailed ? null : handle;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载子文件。
|
|
/// </summary>
|
|
/// <param name="location">资源定位地址。</param>
|
|
/// <param name="assetName">子资源名称。</param>
|
|
/// <param name="cancellationToken">取消操作Token。</param>
|
|
/// <typeparam name="T">资源实例类型。</typeparam>
|
|
/// <returns>原生文件资源实例。</returns>
|
|
public async UniTask<T> LoadSubAssetAsync<T>(string location, string assetName, CancellationToken cancellationToken = default) where T : Object
|
|
{
|
|
var assetInfo = GetAssetInfo(location);
|
|
if (assetInfo == null)
|
|
{
|
|
Log.Fatal($"AssetsInfo is null");
|
|
return null;
|
|
}
|
|
|
|
SubAssetsOperationHandle handle = YooAssets.LoadSubAssetsAsync(assetInfo);
|
|
|
|
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
|
|
|
|
handle.Dispose();
|
|
|
|
return cancelOrFailed ? null : handle.GetSubAssetObject<T>(assetName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载子文件。
|
|
/// </summary>
|
|
/// <param name="location">资源定位地址。</param>
|
|
/// <param name="cancellationToken">取消操作Token。</param>
|
|
/// <typeparam name="T">资源实例类型。</typeparam>
|
|
/// <returns>原生文件资源实例。</returns>
|
|
public async UniTask<T[]> LoadAllSubAssetAsync<T>(string location, CancellationToken cancellationToken = default) where T : Object
|
|
{
|
|
var assetInfo = GetAssetInfo(location);
|
|
if (assetInfo == null)
|
|
{
|
|
Log.Fatal($"AssetsInfo is null");
|
|
return null;
|
|
}
|
|
|
|
SubAssetsOperationHandle handle = YooAssets.LoadSubAssetsAsync(assetInfo);
|
|
|
|
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
|
|
|
|
handle.Dispose();
|
|
|
|
return cancelOrFailed ? null : handle.GetSubAssetObjects<T>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步加载场景。
|
|
/// </summary>
|
|
/// <param name="location">场景的定位地址。</param>
|
|
/// <param name="cancellationToken">取消操作Token。</param>
|
|
/// <param name="sceneMode">场景加载模式。</param>
|
|
/// <param name="activateOnLoad">加载完毕时是否主动激活。</param>
|
|
/// <param name="priority">加载优先级。</param>
|
|
/// <returns>场景资源实例。</returns>
|
|
public async UniTask<Scene> LoadSceneAsyncByUniTask(string location, CancellationToken cancellationToken = default,
|
|
LoadSceneMode sceneMode = LoadSceneMode.Single,
|
|
bool activateOnLoad = true, int priority = 100)
|
|
{
|
|
SceneOperationHandle handle = YooAssets.LoadSceneAsync(location, sceneMode, activateOnLoad, priority);
|
|
|
|
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
|
|
|
|
return cancelOrFailed ? default : handle.SceneObject;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 资源管理日志实现器。
|
|
/// </summary>
|
|
internal class AssetsLogger : YooAsset.ILogger
|
|
{
|
|
public void Log(string message)
|
|
{
|
|
TEngine.Log.Info(message);
|
|
}
|
|
|
|
public void Warning(string message)
|
|
{
|
|
TEngine.Log.Warning(message);
|
|
}
|
|
|
|
public void Error(string message)
|
|
{
|
|
TEngine.Log.Error(message);
|
|
}
|
|
|
|
public void Exception(System.Exception exception)
|
|
{
|
|
TEngine.Log.Fatal(exception.Message);
|
|
}
|
|
}
|
|
} |