AlicizaX/Client/Packages/com.alicizax.unity.resource/Runtime/Resource/ResourceComponent.cs

270 lines
8.5 KiB
C#
Raw Normal View History

2025-01-23 19:06:48 +08:00
using System;
2025-04-28 19:45:45 +08:00
using AlicizaX;
2025-01-23 19:06:48 +08:00
using UnityEngine;
2025-04-28 19:45:45 +08:00
using UnityEngine.Serialization;
2025-01-23 19:06:48 +08:00
using YooAsset;
namespace AlicizaX.Resource.Runtime
{
2025-04-28 19:45:45 +08:00
/// <summary>
/// 资源组件。
/// </summary>
2025-01-23 19:06:48 +08:00
[DisallowMultipleComponent]
2025-04-28 19:45:45 +08:00
public class ResourceComponent : MonoBehaviour
2025-01-23 19:06:48 +08:00
{
#region Propreties
2025-04-28 19:45:45 +08:00
private const int DEFAULT_PRIORITY = 0;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
private IResourceModule _resourceModule;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
private bool _forceUnloadUnusedAssets = false;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
private bool _preorderUnloadUnusedAssets = false;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
private bool _performGCCollect = false;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
private AsyncOperation _asyncOperation = null;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
private float _lastUnloadUnusedAssetsOperationElapseSeconds = 0f;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField] private float minUnloadUnusedAssetsInterval = 60f;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField] private float maxUnloadUnusedAssetsInterval = 300f;
2025-02-06 17:59:35 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField] private bool useSystemUnloadUnusedAssets = true;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField] private string _decryptionServices = "";
2025-01-23 19:06:48 +08:00
/// <summary>
/// 当前最新的包裹版本。
/// </summary>
public string PackageVersion { set; get; }
/// <summary>
2025-04-28 19:45:45 +08:00
/// 资源包名称。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
[SerializeField] private string packageName = "DefaultPackage";
2025-01-23 19:06:48 +08:00
/// <summary>
2025-04-28 19:45:45 +08:00
/// 资源包名称。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public string PackageName
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => packageName;
set => packageName = value;
2025-01-23 19:06:48 +08:00
}
/// <summary>
2025-04-28 19:45:45 +08:00
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
[SerializeField] public long milliseconds = 30;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
public int downloadingMaxNum = 10;
2025-01-23 19:06:48 +08:00
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取或设置同时最大下载数目。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public int DownloadingMaxNum
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => downloadingMaxNum;
set => downloadingMaxNum = value;
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
[SerializeField] public int failedTryAgain = 3;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
public int FailedTryAgain
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => failedTryAgain;
set => failedTryAgain = value;
2025-01-23 19:06:48 +08:00
}
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取当前资源适用的游戏版本号。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public string ApplicableGameVersion => _resourceModule.ApplicableGameVersion;
2025-01-23 19:06:48 +08:00
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取当前内部资源版本号。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public int InternalResourceVersion => _resourceModule.InternalResourceVersion;
2025-01-23 19:06:48 +08:00
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取或设置无用资源释放的最小间隔时间,以秒为单位。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public float MinUnloadUnusedAssetsInterval
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => minUnloadUnusedAssetsInterval;
set => minUnloadUnusedAssetsInterval = value;
2025-01-23 19:06:48 +08:00
}
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取或设置无用资源释放的最大间隔时间,以秒为单位。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public float MaxUnloadUnusedAssetsInterval
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => maxUnloadUnusedAssetsInterval;
set => maxUnloadUnusedAssetsInterval = value;
2025-01-23 19:06:48 +08:00
}
/// <summary>
2025-04-28 19:45:45 +08:00
/// 使用系统释放无用资源策略。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public bool UseSystemUnloadUnusedAssets
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => useSystemUnloadUnusedAssets;
set => useSystemUnloadUnusedAssets = value;
2025-01-23 19:06:48 +08:00
}
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取无用资源释放的等待时长,以秒为单位。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public float LastUnloadUnusedAssetsOperationElapseSeconds => _lastUnloadUnusedAssetsOperationElapseSeconds;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField] private float assetAutoReleaseInterval = 60f;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField] private int assetCapacity = 64;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField] private float assetExpireTime = 60f;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField] private int assetPriority = 0;
2025-01-23 19:06:48 +08:00
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取或设置资源对象池自动释放可释放对象的间隔秒数。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public float AssetAutoReleaseInterval
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => _resourceModule.AssetAutoReleaseInterval;
set => _resourceModule.AssetAutoReleaseInterval = assetAutoReleaseInterval = value;
2025-01-23 19:06:48 +08:00
}
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取或设置资源对象池的容量。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public int AssetCapacity
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => _resourceModule.AssetCapacity;
set => _resourceModule.AssetCapacity = assetCapacity = value;
2025-01-23 19:06:48 +08:00
}
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取或设置资源对象池对象过期秒数。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public float AssetExpireTime
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => _resourceModule.AssetExpireTime;
set => _resourceModule.AssetExpireTime = assetExpireTime = value;
2025-01-23 19:06:48 +08:00
}
/// <summary>
2025-04-28 19:45:45 +08:00
/// 获取或设置资源对象池的优先级。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
public int AssetPriority
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
get => _resourceModule.AssetPriority;
set => _resourceModule.AssetPriority = assetPriority = value;
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
#endregion
private void Awake()
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
_resourceModule = ModuleSystem.RegisterModule<IResourceModule,ResourceModule>();
if (_resourceModule == null)
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
Log.Error("Resource module is invalid.");
return;
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
Application.lowMemory += OnLowMemory;
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
public static string PrefsKey = Application.dataPath.GetHashCode() + "GamePlayMode";
private void Start()
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
EPlayMode playMode = EPlayMode.EditorSimulateMode;
#if UNITY_EDITOR
playMode = (EPlayMode)UnityEditor.EditorPrefs.GetInt(PrefsKey, 0);
#else
playMode = (EPlayMode)AppBuilderSetting.Instance.ResMode;
#endif
_resourceModule.DefaultPackageName = PackageName;
_resourceModule.DecryptionServices = _decryptionServices;
_resourceModule.PlayMode = playMode;
_resourceModule.Milliseconds = milliseconds;
_resourceModule.DownloadingMaxNum = DownloadingMaxNum;
_resourceModule.FailedTryAgain = FailedTryAgain;
_resourceModule.Initialize();
_resourceModule.AssetAutoReleaseInterval = assetAutoReleaseInterval;
_resourceModule.AssetCapacity = assetCapacity;
_resourceModule.AssetExpireTime = assetExpireTime;
_resourceModule.AssetPriority = assetPriority;
_resourceModule.SetForceUnloadUnusedAssetsAction(ForceUnloadUnusedAssets);
Log.Info($"ResourceModule Run Mode{playMode}");
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
private void OnApplicationQuit()
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
Application.lowMemory -= OnLowMemory;
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
#region
2025-01-23 19:06:48 +08:00
/// <summary>
2025-04-28 19:45:45 +08:00
/// 强制执行释放未被使用的资源。
2025-01-23 19:06:48 +08:00
/// </summary>
2025-04-28 19:45:45 +08:00
/// <param name="performGCCollect">是否使用垃圾回收。</param>
public void ForceUnloadUnusedAssets(bool performGCCollect)
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
_forceUnloadUnusedAssets = true;
if (performGCCollect)
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
_performGCCollect = true;
2025-01-23 19:06:48 +08:00
}
}
2025-04-28 19:45:45 +08:00
private void Update()
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
_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();
}
}
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
private void OnLowMemory()
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
Log.Warning("Low memory reported...");
if (_resourceModule != null)
{
_resourceModule.OnLowMemory();
}
2025-01-23 19:06:48 +08:00
}
#endregion
}
2025-01-24 16:21:00 +08:00
}