Files
Continentis/Assets/Scripts/ScriptExtensions/Addressables/AssetLoader.cs
SoulliesOfficial 9b1b5ca93f initial
2025-10-03 00:02:43 -04:00

107 lines
4.0 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.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace SoulliesFramework.General
{
/// <summary>
/// 静态的Addressables资源加载器负责加载和释放资源。
/// 警告:此类不处理依赖关系,仅管理通过它加载的资源的生命周期。
/// </summary>
public static class AssetLoader
{
// 使用字典缓存已加载资源的句柄Key为资源的Address。
// 这样可以防止同一资源被重复加载,并方便我们后续释放。
private static Dictionary<string, AsyncOperationHandle> CachedHandles = new Dictionary<string, AsyncOperationHandle>();
public static List<T> LoadAssetsWithLabel<T>(string label) where T : Object
{
return Addressables.LoadAssetsAsync<T>(label, null).WaitForCompletion().ToList();
}
public static Task<IList<T>> LoadAssetsWithLabelAsync<T>(string label) where T : Object
{
return Addressables.LoadAssetsAsync<T>(label, null).Task;
}
public static T LoadAsset<T>(string address) where T : Object
{
return Addressables.LoadAssetAsync<T>(address).WaitForCompletion();
}
/// <summary>
/// 异步加载指定类型的资源。
/// </summary>
/// <typeparam name="T">要加载的资源类型 (e.g., GameObject, Sprite, AudioClip)</typeparam>
/// <param name="address">资源的Addressable地址</param>
/// <returns>返回加载到的资源如果失败则返回null</returns>
public static async Task<T> LoadAssetAsync<T>(string address) where T : Object
{
// 1. 检查句柄是否已经被缓存
if (CachedHandles.TryGetValue(address, out var handle))
{
// 如果句柄存在,直接返回其结果
return handle.Result as T;
}
// 2. 如果没有缓存,则异步加载资源
AsyncOperationHandle<T> newHandle = Addressables.LoadAssetAsync<T>(address);
// 3. 等待加载完成
T result = await newHandle.Task;
// 4. 检查加载是否成功,如果成功则缓存句柄
if (newHandle.Status == AsyncOperationStatus.Succeeded)
{
// 注意:我们缓存的是通用的句柄,而不是带泛型的句柄
CachedHandles[address] = newHandle;
return result;
}
else
{
Debug.LogError($"[AssetLoader] Failed to load asset at address: {address}");
return null;
}
}
/// <summary>
/// 释放指定地址的资源。
/// </summary>
/// <param name="address">要释放资源的Addressable地址</param>
public static void ReleaseAsset(string address)
{
if (CachedHandles.TryGetValue(address, out var handle))
{
// 从缓存中移除
CachedHandles.Remove(address);
// 释放句柄,这会减少资源的引用计数
Addressables.Release(handle);
Debug.Log($"[AssetLoader] Released asset: {address}");
}
else
{
Debug.LogWarning($"[AssetLoader] Tried to release an asset that was not loaded through this loader: {address}");
}
}
/// <summary>
/// 释放所有通过此类加载的资源。
/// 通常在切换场景或退出游戏时调用。
/// </summary>
public static void ReleaseAllAssets()
{
foreach (var pair in CachedHandles)
{
Addressables.Release(pair.Value);
}
CachedHandles.Clear();
Debug.Log("[AssetLoader] All cached assets released.");
}
}
}