com.alicizax.unity.framework/Runtime/Resource/Resource/ResourceComponent.cs

280 lines
8.9 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 AlicizaX;
using UnityEngine;
using UnityEngine.Serialization;
using YooAsset;
namespace AlicizaX.Resource.Runtime
{
/// <summary>
/// 资源组件。
/// </summary>
[DisallowMultipleComponent]
public class ResourceComponent : 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;
[SerializeField] private string decryptionServices = "";
/// <summary>
/// 自动释放资源引用计数为0的资源包
/// </summary>
[SerializeField] public bool autoUnloadBundleWhenUnused = false;
[SerializeField] private EPlayMode _playMode = EPlayMode.EditorSimulateMode;
/// <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] 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
public void SetPlayMode(int playMode)
{
_playMode = (EPlayMode)playMode;
}
private void Awake()
{
_resourceModule = ModuleSystem.RegisterModule<IResourceModule, ResourceModule>();
if (_resourceModule == null)
{
Log.Error("Resource module is invalid.");
return;
}
Application.lowMemory += OnLowMemory;
}
public static string PrefsKey = Application.dataPath.GetHashCode() + "GamePlayMode";
private void Start()
{
#if UNITY_EDITOR
_playMode = (EPlayMode)UnityEditor.EditorPrefs.GetInt(ResourceComponent.PrefsKey, 0);
#endif
_resourceModule.DefaultPackageName = PackageName;
_resourceModule.DecryptionServices = decryptionServices;
_resourceModule.AutoUnloadBundleWhenUnused = autoUnloadBundleWhenUnused;
_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}");
}
private void OnApplicationQuit()
{
Application.lowMemory -= OnLowMemory;
}
#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();
}
}
}
private void OnLowMemory()
{
Log.Warning("Low memory reported...");
if (_resourceModule != null)
{
_resourceModule.OnLowMemory();
}
}
#endregion
}
}