Files
TEngine/Assets/TEngine/Runtime/GameFramework/Resource/ResourceManager.cs
ALEXTANG 5d83df6b29 ResourceModule
ResourceModule
2023-04-04 16:04:55 +08:00

506 lines
17 KiB
C#

using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.SceneManagement;
using YooAsset;
namespace TEngine
{
/// <summary>
/// 资源管理器。
/// </summary>
internal partial class ResourceManager: GameFrameworkModule,IResourceManager
{
#region Propreties
/// <summary>
/// 资源包名称。
/// </summary>
public string PackageName { get; set; } = "DefaultPackage";
/// <summary>
/// 获取当前资源适用的游戏版本号。
/// </summary>
public string ApplicableGameVersion => m_ApplicableGameVersion;
private string m_ApplicableGameVersion;
/// <summary>
/// 获取当前内部资源版本号。
/// </summary>
public int InternalResourceVersion => m_InternalResourceVersion;
private int m_InternalResourceVersion;
/// <summary>
/// 同时下载的最大数目。
/// </summary>
public int DownloadingMaxNum { get; set; }
/// <summary>
/// 失败重试最大数目。
/// </summary>
public int FailedTryAgain { get; set; }
/// <summary>
/// 获取资源只读区路径。
/// </summary>
public string ReadOnlyPath => m_ReadOnlyPath;
private string m_ReadOnlyPath;
/// <summary>
/// 获取资源读写区路径。
/// </summary>
public string ReadWritePath => m_ReadWritePath;
private string m_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 string HostServerURL { get; set; }
#endregion
#region
internal override void Update(float elapseSeconds, float realElapseSeconds)
{
}
internal override void Shutdown()
{
YooAssets.Destroy();
}
#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.");
}
m_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.");
}
m_ReadWritePath = readWritePath;
}
#endregion
public void Initialize()
{
// 初始化资源系统
YooAssets.Initialize(new YooAssetsLogger());
YooAssets.SetOperationSystemMaxTimeSlice(Milliseconds);
YooAssets.SetCacheSystemCachedFileVerifyLevel(VerifyLevel);
// 创建默认的资源包
string packageName = PackageName;
var defaultPackage = YooAssets.TryGetPackage(packageName);
if (defaultPackage == null)
{
defaultPackage = YooAssets.CreatePackage(packageName);
YooAssets.SetDefaultPackage(defaultPackage);
}
}
public InitializationOperation InitPackage()
{
// 创建默认的资源包
string packageName = PackageName;
var package = YooAssets.TryGetPackage(packageName);
if (package == null)
{
package = YooAssets.CreatePackage(packageName);
YooAssets.SetDefaultPackage(package);
}
// 编辑器下的模拟模式
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.QueryServices = new GameQueryServices();
createParameters.DefaultHostServer = HostServerURL;
createParameters.FallbackHostServer = HostServerURL;
initializationOperation = package.InitializeAsync(createParameters);
}
return initializationOperation;
}
public void UnloadAsset(object asset)
{
throw new System.NotImplementedException();
}
public void UnloadUnusedAssets()
{
YooAssets.UnloadUnusedAssets();
}
public void ForceUnloadAllAssets()
{
YooAssets.ForceUnloadAllAssets();
}
public HasAssetResult HasAsset(string assetName)
{
if (string.IsNullOrEmpty(assetName))
{
throw new GameFrameworkException("Asset name is invalid.");
}
AssetInfo assetInfo = YooAssets.GetAssetInfo(assetName);
if (!CheckLocationValid(assetName))
{
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);
}
#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="assetName">要加载资源的名称。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam>
/// <returns>资源实例。</returns>
public T LoadAsset<T>(string assetName) where T : Object
{
if (string.IsNullOrEmpty(assetName))
{
Log.Error("Asset name is invalid.");
return default;
}
AssetOperationHandle handle = YooAssets.LoadAssetSync<T>(assetName);
if (typeof(T) == typeof(GameObject))
{
GameObject ret = handle.InstantiateSync();
BindAssetTag(ret, handle, assetName);
return ret as T;
}
else
{
return handle.AssetObject as T;
}
}
/// <summary>
/// 同步加载资源。
/// </summary>
/// <param name="assetName">要加载资源的名称。</param>
/// <param name="parent">父节点位置。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam>
/// <returns>资源实例。</returns>
public T LoadAsset<T>(string assetName, Transform parent) where T : Object
{
if (string.IsNullOrEmpty(assetName))
{
Log.Error("Asset name is invalid.");
return default;
}
AssetOperationHandle handle = YooAssets.LoadAssetSync<T>(assetName);
if (typeof(T) == typeof(GameObject))
{
GameObject ret = handle.InstantiateSync(parent);
BindAssetTag(ret, handle, assetName);
return ret as T;
}
else
{
return handle.AssetObject as T;
}
}
/// <summary>
/// 同步加载资源。
/// </summary>
/// <param name="handle">资源操作句柄。</param>
/// <param name="assetName">要加载资源的名称。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam>
/// <returns>资源实例。</returns>
public T LoadAsset<T>(string assetName,out AssetOperationHandle handle) where T : Object
{
handle = YooAssets.LoadAssetSync<T>(assetName);
if (string.IsNullOrEmpty(assetName))
{
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="assetName">要加载资源的名称。</param>
/// <param name="handle">资源操作句柄。</param>
/// <param name="parent">父节点位置。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam>
/// <returns>资源实例。</returns>
public T LoadAsset<T>(string assetName, Transform parent,out AssetOperationHandle handle) where T : Object
{
handle = YooAssets.LoadAssetSync<T>(assetName);
if (string.IsNullOrEmpty(assetName))
{
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="assetName">要加载的实例名称。</param>
/// <param name="cancellationToken">取消操作Token。</param>
/// <returns>资源实实例。</returns>
public async UniTask<T> LoadAssetAsync<T>(string assetName, CancellationToken cancellationToken) where T : Object
{
AssetOperationHandle handle = LoadAssetAsyncHandle<GameObject>(assetName);
await handle.ToUniTask(cancellationToken:cancellationToken);
return handle.AssetObject as T;
}
/// <summary>
/// 异步加载游戏物体。
/// </summary>
/// <param name="assetName">要加载的游戏物体名称。</param>
/// <param name="cancellationToken">取消操作Token。</param>
/// <returns>异步游戏物体实例。</returns>
public async UniTask<GameObject> LoadGameObjectAsync(string assetName, CancellationToken cancellationToken)
{
AssetOperationHandle handle = LoadAssetAsyncHandle<GameObject>(assetName);
await handle.ToUniTask(cancellationToken:cancellationToken);
GameObject ret = handle.InstantiateSync();
BindAssetTag(ret, handle, assetName);
return ret;
}
/// <summary>
/// 同步加载资源并获取句柄。
/// </summary>
/// <param name="assetName">要加载资源的名称。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam>
/// <returns>同步加载资源句柄。</returns>
public AssetOperationHandle LoadAssetGetOperation<T>(string assetName) where T : Object
{
return YooAssets.LoadAssetSync<T>(assetName);
}
/// <summary>
/// 异步加载资源并获取句柄。
/// </summary>
/// <param name="assetName">要加载资源的名称。</param>
/// <typeparam name="T">要加载资源的类型。</typeparam>
/// <returns>异步加载资源句柄。</returns>
public AssetOperationHandle LoadAssetAsyncHandle<T>(string assetName) where T : Object
{
return YooAssets.LoadAssetAsync<T>(assetName);
}
/// <summary>
/// 异步加载场景。
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="activateOnLoad">加载完毕时是否主动激活</param>
/// <param name="priority">优先级</param>
/// <returns>异步加载场景句柄。</returns>
public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
{
return YooAssets.LoadSceneAsync(location,sceneMode,activateOnLoad,priority);
}
/// <summary>
/// 异步加载场景
/// </summary>
/// <param name="assetInfo">场景的资源信息</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="activateOnLoad">加载完毕时是否主动激活</param>
/// <param name="priority">优先级</param>
/// <returns>异步加载场景句柄。</returns>
public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
{
return YooAssets.LoadSceneAsync(assetInfo,sceneMode,activateOnLoad,priority);
}
private bool BindAssetTag(GameObject go,AssetOperationHandle handle,string location)
{
if (go == null)
{
throw new GameFrameworkException($"ResourceMgr BindAssetTag Failed! GameObject is null!");
}
if (handle == null)
{
throw new GameFrameworkException($"ResourceMgr BindAssetTag Failed! AssetOperationHandle is null!");
}
go.AddComponent<AssetTag>().Bind(handle,location);
return true;
}
}
}