2025-04-21 21:14:23 +08:00

312 lines
9.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using UnityEngine;
using UnityEngine.Serialization;
using YooAsset;
namespace TEngine
{
/// <summary>
/// 资源组件。
/// </summary>
[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;
/// <summary>
/// 当前最新的包裹版本。
/// </summary>
public string PackageVersion { set; get; }
/// <summary>
/// 资源包名称。
/// </summary>
[SerializeField]
private string packageName = "DefaultPackage";
/// <summary>
/// 资源包名称。
/// </summary>
public string PackageName
{
get => packageName;
set => packageName = value;
}
/// <summary>
/// 资源系统运行模式。
/// </summary>
[SerializeField]
private EPlayMode playMode = EPlayMode.EditorSimulateMode;
/// <summary>
/// 资源系统运行模式。
/// <remarks>编辑器内优先使用。</remarks>
/// </summary>
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;
/// <summary>
/// 资源模块的加密类型。
/// </summary>
public EncryptionType EncryptionType => encryptionType;
/// <summary>
/// 是否支持边玩边下载。
/// </summary>
[SerializeField]
private bool updatableWhilePlaying = false;
/// <summary>
/// 是否支持边玩边下载。
/// </summary>
public bool UpdatableWhilePlaying => updatableWhilePlaying;
/// <summary>
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)
/// </summary>
[SerializeField]
public long milliseconds = 30;
public int downloadingMaxNum = 10;
/// <summary>
/// 获取或设置同时最大下载数目。
/// </summary>
public int DownloadingMaxNum
{
get => downloadingMaxNum;
set => downloadingMaxNum = value;
}
[SerializeField]
public int failedTryAgain = 3;
public int FailedTryAgain
{
get => failedTryAgain;
set => failedTryAgain = value;
}
/// <summary>
/// 获取当前资源适用的游戏版本号。
/// </summary>
public string ApplicableGameVersion => _resourceModule.ApplicableGameVersion;
/// <summary>
/// 获取当前内部资源版本号。
/// </summary>
public int InternalResourceVersion => _resourceModule.InternalResourceVersion;
/// <summary>
/// 获取或设置无用资源释放的最小间隔时间,以秒为单位。
/// </summary>
public float MinUnloadUnusedAssetsInterval
{
get => minUnloadUnusedAssetsInterval;
set => minUnloadUnusedAssetsInterval = value;
}
/// <summary>
/// 获取或设置无用资源释放的最大间隔时间,以秒为单位。
/// </summary>
public float MaxUnloadUnusedAssetsInterval
{
get => maxUnloadUnusedAssetsInterval;
set => maxUnloadUnusedAssetsInterval = value;
}
/// <summary>
/// 使用系统释放无用资源策略。
/// </summary>
public bool UseSystemUnloadUnusedAssets
{
get => useSystemUnloadUnusedAssets;
set => useSystemUnloadUnusedAssets = value;
}
/// <summary>
/// 获取无用资源释放的等待时长,以秒为单位。
/// </summary>
public float LastUnloadUnusedAssetsOperationElapseSeconds => _lastUnloadUnusedAssetsOperationElapseSeconds;
[SerializeField]
private float assetAutoReleaseInterval = 60f;
[SerializeField]
private int assetCapacity = 64;
[SerializeField]
private float assetExpireTime = 60f;
[SerializeField]
private int assetPriority = 0;
/// <summary>
/// 获取或设置资源对象池自动释放可释放对象的间隔秒数。
/// </summary>
public float AssetAutoReleaseInterval
{
get => _resourceModule.AssetAutoReleaseInterval;
set => _resourceModule.AssetAutoReleaseInterval = assetAutoReleaseInterval = value;
}
/// <summary>
/// 获取或设置资源对象池的容量。
/// </summary>
public int AssetCapacity
{
get => _resourceModule.AssetCapacity;
set => _resourceModule.AssetCapacity = assetCapacity = value;
}
/// <summary>
/// 获取或设置资源对象池对象过期秒数。
/// </summary>
public float AssetExpireTime
{
get => _resourceModule.AssetExpireTime;
set => _resourceModule.AssetExpireTime = assetExpireTime = value;
}
/// <summary>
/// 获取或设置资源对象池的优先级。
/// </summary>
public int AssetPriority
{
get => _resourceModule.AssetPriority;
set => _resourceModule.AssetPriority = assetPriority = value;
}
#endregion
private void Start()
{
_resourceModule = ModuleSystem.GetModule<IResourceModule>();
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
/// <summary>
/// 强制执行释放未被使用的资源。
/// </summary>
/// <param name="performGCCollect">是否使用垃圾回收。</param>
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
}
}