Files
TEngine/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs
ALEXTANG 5e70e7972e 更新资源模块接口
更新资源模块接口
2023-10-16 13:03:41 +08:00

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);
}
}
}