using System; using System.Threading; using AlicizaX.Runtime; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.SceneManagement; using YooAsset; namespace AlicizaX.Resource.Runtime { [DisallowMultipleComponent] [AddComponentMenu("Game Framework/ResourceComponent")] [UnityEngine.Scripting.Preserve] public class ResourceComponent : GameFrameworkComponent { #region Propreties [Tooltip("当目标平台为Web平台时,将会强制设置为" + nameof(EPlayMode.WebPlayMode))] [SerializeField] private EPlayMode m_GamePlayMode; [SerializeField] private long m_Milliseconds = 30; [SerializeField] private string m_defaultPackageName = "DefaultPackage"; [SerializeField] private float m_AssetAutoReleaseInterval = 60; [SerializeField] private int m_AssetCapacity = 64; [SerializeField] private float m_AssetExpireTime = 60; [SerializeField] private int m_AssetPriority = 0; /// /// 资源的运行模式 /// public EPlayMode GamePlayMode { get { return m_GamePlayMode; } set { m_GamePlayMode = value; } } public const int DefaultPriority = 0; private IResourceManager m_ResourceManager; /// /// 当前最新的包裹版本。 /// public string PackageVersion { set; get; } #endregion private void OnDestroy() { m_ResourceManager = null; } protected override void Awake() { ImplementationComponentType = Utility.Assembly.GetType(componentType); InterfaceComponentType = typeof(IResourceManager); base.Awake(); m_ResourceManager = SysModuleCenter.GetModule(); } private static string PrefsKey => Application.dataPath.GetHashCode() + "GamePlayMode"; protected void Start() { #if UNITY_EDITOR m_GamePlayMode = (EPlayMode)UnityEditor.EditorPrefs.GetInt(PrefsKey, 0); #endif // m_ResourceManager.SetReadOnlyPath(Application.streamingAssetsPath); // if (config.ReadWritePathType == ReadWritePathType.TemporaryCache) // { // m_ResourceManager.SetReadWritePath(Application.temporaryCachePath); // } // else // { // m_ResourceManager.SetReadWritePath(Application.persistentDataPath); // } m_ResourceManager.DefaultPackageName = m_defaultPackageName; m_ResourceManager.PlayMode = m_GamePlayMode; m_ResourceManager.VerifyLevel = EFileVerifyLevel.Middle; m_ResourceManager.Milliseconds = m_Milliseconds; m_ResourceManager.InstanceRoot = transform; m_ResourceManager.Initialize(); m_ResourceManager.AssetAutoReleaseInterval = m_AssetAutoReleaseInterval; m_ResourceManager.AssetCapacity = m_AssetCapacity; m_ResourceManager.AssetExpireTime = m_AssetExpireTime; m_ResourceManager.AssetPriority = m_AssetPriority; Log.Info($"ResourceComponent Run Mode:{m_GamePlayMode}"); } /// /// 初始化操作。 /// /// public async UniTask InitPackageAsync(string packageName = "", string host = "", string fallbackHostServer = "", bool isDefaultPackage = true) { if (m_ResourceManager == null) { Log.Error("Resource component is invalid."); return false; } if (string.IsNullOrEmpty(packageName)) { packageName = m_defaultPackageName; } return await m_ResourceManager.InitPackageAsync(packageName, host, fallbackHostServer, isDefaultPackage); } #region 版本更新 /// /// 获取当前资源包版本。 /// /// 指定资源包的名称。不传使用默认资源包 /// 资源包版本。 public string GetPackageVersion(string customPackageName = "") { var package = string.IsNullOrEmpty(customPackageName) ? YooAssets.GetPackage(m_defaultPackageName) : YooAssets.GetPackage(customPackageName); if (package == null) { return string.Empty; } return package.GetPackageVersion(); } /// /// 异步更新最新包的版本。 /// /// 请求URL是否需要带时间戳。 /// 超时时间。 /// 指定资源包的名称。不传使用默认资源包 /// 请求远端包裹的最新版本操作句柄。 public RequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks = false, int timeout = 60, string customPackageName = "") { var package = string.IsNullOrEmpty(customPackageName) ? YooAssets.GetPackage(m_defaultPackageName) : YooAssets.GetPackage(customPackageName); return package.RequestPackageVersionAsync(appendTimeTicks, timeout); } /// /// 向网络端请求并更新清单 /// /// 更新的包裹版本 /// 更新成功后自动保存版本号,作为下次初始化的版本。 /// 超时时间(默认值:60秒) /// 指定资源包的名称。不传使用默认资源包 public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout = 60, string customPackageName = "") { var package = string.IsNullOrEmpty(customPackageName) ? YooAssets.GetPackage(m_defaultPackageName) : YooAssets.GetPackage(customPackageName); return package.UpdatePackageManifestAsync(packageVersion, timeout); } /// /// 清理包裹未使用的缓存文件。 /// /// 指定资源包的名称。不传使用默认资源包 public ClearUnusedBundleFilesOperation ClearUnusedCacheFilesAsync(string customPackageName = "") { var package = string.IsNullOrEmpty(customPackageName) ? YooAssets.GetPackage(m_defaultPackageName) : YooAssets.GetPackage(customPackageName); return package.ClearUnusedBundleFilesAsync(); } #endregion #region 加载场景 /// /// 异步加载场景 /// /// 资源路径 /// 场景模式 /// 是否加载完成自动激活 /// public UniTask LoadSceneAsync(string path, LoadSceneMode sceneMode, bool activateOnLoad = true) { return m_ResourceManager.LoadSceneAsync(path, sceneMode, activateOnLoad); } /// /// 异步加载场景 /// /// 资源路径 /// 场景模式 /// 是否加载完成自动激活 /// public UniTask LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad = true) { return m_ResourceManager.LoadSceneAsync(assetInfo, sceneMode, activateOnLoad); } #endregion #region 获取资源 /// /// 检查资源是否存在。 /// /// 要检查资源的名称。 /// 指定资源包的名称。不传使用默认资源包 /// 检查资源是否存在的结果。 public HasAssetResult HasAsset(string location, string customPackageName = "") { return m_ResourceManager.HasAsset(location, packageName: customPackageName); } /// /// 检查资源定位地址是否有效。 /// /// 资源的定位地址 /// 指定资源包的名称。不传使用默认资源包 public bool CheckLocationValid(string location, string customPackageName = "") { return m_ResourceManager.CheckLocationValid(location, packageName: customPackageName); } /// /// 获取资源信息列表。 /// /// 资源标签。 /// 指定资源包的名称。不传使用默认资源包 /// 资源信息列表。 public AssetInfo[] GetAssetInfos(string resTag, string customPackageName = "") { return m_ResourceManager.GetAssetInfos(resTag, packageName: customPackageName); } /// /// 获取资源信息列表。 /// /// 资源标签列表。 /// 指定资源包的名称。不传使用默认资源包 /// 资源信息列表。 public AssetInfo[] GetAssetInfos(string[] tags, string customPackageName = "") { return m_ResourceManager.GetAssetInfos(tags, packageName: customPackageName); } /// /// 获取资源信息。 /// /// 资源的定位地址。 /// 指定资源包的名称。不传使用默认资源包 /// 资源信息。 public AssetInfo GetAssetInfo(string location, string customPackageName = "") { return m_ResourceManager.GetAssetInfo(location, packageName: customPackageName); } #endregion #region 加载资源 /// /// 异步加载资源。 /// /// 资源的定位地址。 /// 要加载资源的类型。 /// 加载资源回调函数集。 /// 用户自定义数据。 /// 指定资源包的名称。不传使用默认资源包。 public void LoadAssetAsync(string location, Type assetType, LoadAssetCallbacks loadAssetCallbacks, object userData = null, string packageName = "") { LoadAssetAsync(location, assetType, DefaultPriority, loadAssetCallbacks, userData, packageName); } /// /// 异步加载资源。 /// /// 资源的定位地址。 /// 要加载资源的类型。 /// 加载资源的优先级。 /// 加载资源回调函数集。 /// 用户自定义数据。 /// 指定资源包的名称。不传使用默认资源包。 public void LoadAssetAsync(string location, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData, string packageName = "") { if (string.IsNullOrEmpty(location)) { Log.Error("Asset name is invalid."); return; } m_ResourceManager.LoadAssetAsync(location, assetType, priority, loadAssetCallbacks, userData, packageName); } /// /// 同步加载资源。 /// /// 资源的定位地址。 /// 指定资源包的名称。不传使用默认资源包。 /// 要加载资源的类型。 /// 资源实例。 public T LoadAsset(string location, string packageName = "") where T : UnityEngine.Object { if (string.IsNullOrEmpty(location)) { Log.Error("Asset name is invalid."); return null; } return m_ResourceManager.LoadAsset(location, packageName); } /// /// 同步加载游戏物体并实例化。 /// /// 资源的定位地址。 /// 资源实例父节点。 /// 指定资源包的名称。不传使用默认资源包。 /// 资源实例。 public GameObject LoadGameObject(string location, Transform parent = null, string packageName = "") { if (string.IsNullOrEmpty(location)) { Log.Error("Asset name is invalid."); return null; } return m_ResourceManager.LoadGameObject(location, parent, packageName); } /// /// 异步加载资源。 /// /// 资源的定位地址。 /// 回调函数。 /// 指定资源包的名称。不传使用默认资源包 /// 要加载资源的类型。 public void LoadAsset(string location, Action callback, string customPackageName = "") where T : UnityEngine.Object { if (string.IsNullOrEmpty(location)) { Log.Error("Asset name is invalid."); return; } m_ResourceManager.LoadAsset(location, callback, packageName: customPackageName); } /// /// 异步加载资源。 /// /// 资源定位地址。 /// 取消操作Token。 /// 指定资源包的名称。不传使用默认资源包。 /// 要加载资源的类型。 /// 异步资源实例。 public async UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default, string packageName = "") where T : UnityEngine.Object { if (string.IsNullOrEmpty(location)) { Log.Error("Asset name is invalid."); return null; } return await m_ResourceManager.LoadAssetAsync(location, cancellationToken, packageName); } /// /// 异步加载游戏物体并实例化。 /// /// 资源定位地址。 /// 资源实例父节点。 /// 取消操作Token。 /// 指定资源包的名称。不传使用默认资源包。 /// 异步游戏物体实例。 public async UniTask LoadGameObjectAsync(string location, Transform parent = null, CancellationToken cancellationToken = default, string packageName = "") { if (string.IsNullOrEmpty(location)) { Log.Error("Asset name is invalid."); return null; } return await m_ResourceManager.LoadGameObjectAsync(location, parent, cancellationToken, packageName); } public AssetHandle LoadAssetGetOperation(string location, string packageName = "") where T : UnityEngine.Object { return m_ResourceManager.LoadAssetGetOperation(location, packageName); } public AssetHandle LoadAssetAsyncHandle(string location, string packageName = "") where T : UnityEngine.Object { return m_ResourceManager.LoadAssetAsyncHandle(location, packageName); } #endregion #region 卸载资源 /// /// 卸载资源。 /// /// 要卸载的资源。 public void UnloadAsset(object asset) { if (asset == null) { return; } m_ResourceManager.UnloadAsset(asset); } #endregion #region 释放资源 /// /// 强制执行释放未被使用的资源。 /// /// 是否使用垃圾回收。 public void ForceUnloadUnusedAssets(bool performGCCollect) { m_ResourceManager.UnloadUnusedAssets(performGCCollect); } /// /// 预订执行释放未被使用的资源。 /// /// 是否使用垃圾回收。 public void UnloadUnusedAssets(bool performGCCollect) { m_ResourceManager.ForceUnloadUnusedAssets(performGCCollect); } #endregion } }