using System; using UnityEngine; using UnityEngine.Serialization; using YooAsset; namespace TEngine { /// /// 资源组件。 /// [DisallowMultipleComponent] public class ResourceModuleDriver : MonoBehaviour { #region Propreties private const int DEFAULT_PRIORITY = 0; private IResourceModule _resourceModule; private bool _forceUnloadUnusedAssets = false; private bool _preorderUnloadUnusedAssets = false; private bool _performGCCollect = false; private AsyncOperation _asyncOperation = null; private float _lastUnloadUnusedAssetsOperationElapseSeconds = 0f; [SerializeField] private float minUnloadUnusedAssetsInterval = 60f; [SerializeField] private float maxUnloadUnusedAssetsInterval = 300f; [SerializeField] private bool useSystemUnloadUnusedAssets = true; /// /// 当前最新的包裹版本。 /// public string PackageVersion { set; get; } /// /// 资源包名称。 /// [SerializeField] private string packageName = "DefaultPackage"; /// /// 资源包名称。 /// public string PackageName { get => packageName; set => packageName = value; } /// /// 资源系统运行模式。 /// [SerializeField] private EPlayMode playMode = EPlayMode.EditorSimulateMode; /// /// 资源系统运行模式。 /// 编辑器内优先使用。 /// public EPlayMode PlayMode { get { #if UNITY_EDITOR //编辑器模式使用。 return (EPlayMode)UnityEditor.EditorPrefs.GetInt("EditorPlayMode"); #else if (playMode == EPlayMode.EditorSimulateMode) { playMode = EPlayMode.OfflinePlayMode; } //运行时使用。 return playMode; #endif } set { #if UNITY_EDITOR playMode = value; #endif } } [SerializeField] private EncryptionType encryptionType = EncryptionType.None; /// /// 资源模块的加密类型。 /// public EncryptionType EncryptionType => encryptionType; /// /// 是否支持边玩边下载。 /// [SerializeField] private bool updatableWhilePlaying = false; /// /// 是否支持边玩边下载。 /// public bool UpdatableWhilePlaying => updatableWhilePlaying; /// /// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒) /// [SerializeField] public long milliseconds = 30; public int downloadingMaxNum = 10; /// /// 获取或设置同时最大下载数目。 /// public int DownloadingMaxNum { get => downloadingMaxNum; set => downloadingMaxNum = value; } [SerializeField] public int failedTryAgain = 3; public int FailedTryAgain { get => failedTryAgain; set => failedTryAgain = value; } /// /// 获取当前资源适用的游戏版本号。 /// public string ApplicableGameVersion => _resourceModule.ApplicableGameVersion; /// /// 获取当前内部资源版本号。 /// public int InternalResourceVersion => _resourceModule.InternalResourceVersion; /// /// 获取或设置无用资源释放的最小间隔时间,以秒为单位。 /// public float MinUnloadUnusedAssetsInterval { get => minUnloadUnusedAssetsInterval; set => minUnloadUnusedAssetsInterval = value; } /// /// 获取或设置无用资源释放的最大间隔时间,以秒为单位。 /// public float MaxUnloadUnusedAssetsInterval { get => maxUnloadUnusedAssetsInterval; set => maxUnloadUnusedAssetsInterval = value; } /// /// 使用系统释放无用资源策略。 /// public bool UseSystemUnloadUnusedAssets { get => useSystemUnloadUnusedAssets; set => useSystemUnloadUnusedAssets = value; } /// /// 获取无用资源释放的等待时长,以秒为单位。 /// public float LastUnloadUnusedAssetsOperationElapseSeconds => _lastUnloadUnusedAssetsOperationElapseSeconds; [SerializeField] private float assetAutoReleaseInterval = 60f; [SerializeField] private int assetCapacity = 64; [SerializeField] private float assetExpireTime = 60f; [SerializeField] private int assetPriority = 0; /// /// 获取或设置资源对象池自动释放可释放对象的间隔秒数。 /// public float AssetAutoReleaseInterval { get => _resourceModule.AssetAutoReleaseInterval; set => _resourceModule.AssetAutoReleaseInterval = assetAutoReleaseInterval = value; } /// /// 获取或设置资源对象池的容量。 /// public int AssetCapacity { get => _resourceModule.AssetCapacity; set => _resourceModule.AssetCapacity = assetCapacity = value; } /// /// 获取或设置资源对象池对象过期秒数。 /// public float AssetExpireTime { get => _resourceModule.AssetExpireTime; set => _resourceModule.AssetExpireTime = assetExpireTime = value; } /// /// 获取或设置资源对象池的优先级。 /// public int AssetPriority { get => _resourceModule.AssetPriority; set => _resourceModule.AssetPriority = assetPriority = value; } #endregion private void Start() { _resourceModule = ModuleSystem.GetModule(); if (_resourceModule == null) { Log.Fatal("Resource module is invalid."); return; } if (PlayMode == EPlayMode.EditorSimulateMode) { Log.Info("During this run, ResourceModule will use editor resource files, which you should validate first."); #if !UNITY_EDITOR PlayMode = EPlayMode.OfflinePlayMode; #endif } _resourceModule.DefaultPackageName = PackageName; _resourceModule.PlayMode = PlayMode; _resourceModule.EncryptionType = encryptionType; _resourceModule.Milliseconds = milliseconds; _resourceModule.HostServerURL = Settings.UpdateSetting.GetResDownLoadPath(); _resourceModule.FallbackHostServerURL = Settings.UpdateSetting.GetFallbackResDownLoadPath(); _resourceModule.DownloadingMaxNum = DownloadingMaxNum; _resourceModule.FailedTryAgain = FailedTryAgain; _resourceModule.UpdatableWhilePlaying = UpdatableWhilePlaying; _resourceModule.Initialize(); _resourceModule.AssetAutoReleaseInterval = assetAutoReleaseInterval; _resourceModule.AssetCapacity = assetCapacity; _resourceModule.AssetExpireTime = assetExpireTime; _resourceModule.AssetPriority = assetPriority; _resourceModule.SetForceUnloadUnusedAssetsAction(ForceUnloadUnusedAssets); Log.Info($"ResourceModule Run Mode:{PlayMode}"); } #region 释放资源 /// /// 强制执行释放未被使用的资源。 /// /// 是否使用垃圾回收。 public void ForceUnloadUnusedAssets(bool performGCCollect) { _forceUnloadUnusedAssets = true; if (performGCCollect) { _performGCCollect = true; } } private void Update() { _lastUnloadUnusedAssetsOperationElapseSeconds += Time.unscaledDeltaTime; if (_asyncOperation == null && (_forceUnloadUnusedAssets || _lastUnloadUnusedAssetsOperationElapseSeconds >= maxUnloadUnusedAssetsInterval || _preorderUnloadUnusedAssets && _lastUnloadUnusedAssetsOperationElapseSeconds >= minUnloadUnusedAssetsInterval)) { Log.Info("Unload unused assets..."); _forceUnloadUnusedAssets = false; _preorderUnloadUnusedAssets = false; _lastUnloadUnusedAssetsOperationElapseSeconds = 0f; _asyncOperation = Resources.UnloadUnusedAssets(); if (useSystemUnloadUnusedAssets) { _resourceModule.UnloadUnusedAssets(); } } if (_asyncOperation is { isDone: true }) { _asyncOperation = null; if (_performGCCollect) { Log.Info("GC.Collect..."); _performGCCollect = false; GC.Collect(); } } } #endregion } }