168 lines
5.4 KiB
C#
168 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using UnityEngine.AddressableAssets.ResourceLocators;
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
|
|
namespace BrewMonster.Scripts
|
|
{
|
|
public class AddressableManager : MonoSingleton<AddressableManager>
|
|
{
|
|
private bool _isInitialized = false;
|
|
|
|
private Dictionary<string, AsyncOperationHandle<GameObject>> _loadedAssets = new();
|
|
private Dictionary<string, AsyncOperationHandle<TextAsset>> _loadedTextAssets = new();
|
|
public event Action OnDispose;
|
|
|
|
protected override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
_isInitialized = false;
|
|
Addressables.InitializeAsync().Completed += OnInitializeComplete;
|
|
}
|
|
|
|
public bool IsInitialized()
|
|
{
|
|
return _isInitialized;
|
|
}
|
|
|
|
void OnInitializeComplete(AsyncOperationHandle<IResourceLocator> handle)
|
|
{
|
|
if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
{
|
|
_isInitialized = true;
|
|
BMLogger.Log($"AddressableManager: Initialized");
|
|
}
|
|
else
|
|
{
|
|
// print out the error
|
|
BMLogger.LogError($"AddressableManager: Failed to initialize: {handle.OperationException?.Message} {handle.OperationException?.StackTrace}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load a text asset asynchronously. The address should look like this: "elements.data"
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="assetPath"></param>
|
|
/// <returns></returns>
|
|
public async Task<TextAsset> LoadTextAssetAsync(string assetPath)
|
|
{
|
|
if (_loadedTextAssets.ContainsKey(assetPath))
|
|
{
|
|
return _loadedTextAssets[assetPath].Result;
|
|
}
|
|
try
|
|
{
|
|
var handle = Addressables.LoadAssetAsync<TextAsset>(assetPath);
|
|
await handle.Task;
|
|
|
|
_loadedTextAssets[assetPath] = handle;
|
|
return handle.Result;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
BMLogger.LogError(e.StackTrace);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load an asset asynchronously. The address should look like this: "models/npcs/npc/魅灵首领/魅灵首领/魅灵首领.prefab"
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<GameObject> LoadPrefabAsync(string assetPath)
|
|
{
|
|
if (_loadedAssets.ContainsKey(assetPath))
|
|
{
|
|
return _loadedAssets[assetPath].Result;
|
|
}
|
|
|
|
try
|
|
{
|
|
var handle = Addressables.LoadAssetAsync<GameObject>(assetPath);
|
|
await handle.Task;
|
|
_loadedAssets[assetPath] = handle;
|
|
return handle.Result;
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
BMLogger.LogError(e.StackTrace);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// When the asset is no longer needed, call this method to unload it.
|
|
/// </summary>
|
|
/// <param name="assetPath">The asset path used when loading the asset</param>
|
|
public void ReleaseAsset(string assetPath)
|
|
{
|
|
if (_loadedAssets.TryGetValue(assetPath, out var handle))
|
|
{
|
|
if (handle.IsValid())
|
|
{
|
|
Addressables.Release(handle);
|
|
}
|
|
_loadedAssets.Remove(assetPath);
|
|
BMLogger.Log($"AddressableManager: Released asset: {assetPath}");
|
|
}
|
|
else
|
|
{
|
|
BMLogger.LogWarning($"AddressableManager: Asset not found in cache: {assetPath}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Release a specific asset by its handle directly.
|
|
/// </summary>
|
|
/// <param name="handle">The async operation handle to release</param>
|
|
public void ReleaseAsset(AsyncOperationHandle<GameObject> handle)
|
|
{
|
|
if (handle.IsValid())
|
|
{
|
|
Addressables.Release(handle);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Release all loaded assets from the cache.
|
|
/// </summary>
|
|
public void ReleaseAllAssets()
|
|
{
|
|
foreach (var kvp in _loadedAssets)
|
|
{
|
|
if (kvp.Value.IsValid())
|
|
{
|
|
Addressables.Release(kvp.Value);
|
|
}
|
|
}
|
|
_loadedAssets.Clear();
|
|
BMLogger.Log("AddressableManager: Released all assets");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if an asset is currently loaded in the cache.
|
|
/// </summary>
|
|
/// <param name="assetPath">The asset path to check</param>
|
|
/// <returns>True if the asset is loaded</returns>
|
|
public bool IsAssetLoaded(string assetPath)
|
|
{
|
|
return _loadedAssets.ContainsKey(assetPath) && _loadedAssets[assetPath].IsValid();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the count of currently loaded assets.
|
|
/// </summary>
|
|
public int LoadedAssetCount => _loadedAssets.Count;
|
|
|
|
private void OnDestroy()
|
|
{
|
|
OnDispose?.Invoke();
|
|
ReleaseAllAssets();
|
|
}
|
|
}
|
|
}
|