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