Update Addressable manager

This commit is contained in:
HungDK
2025-12-25 16:41:11 +07:00
parent c432556ec8
commit 325e1e25b6
2 changed files with 116 additions and 8 deletions
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
@@ -43,32 +44,131 @@ namespace BrewMonster.Scripts
}
/// <summary>
/// Load a text asset asynchronously. The address should look like this: "elements.data"
/// Load a text asset asynchronously.
/// NOTE: The key must match the Addressables "Address" (or another valid key like a label/GUID).
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assetPath"></param>
/// <returns></returns>
public async Task<TextAsset> LoadTextAssetAsync(string assetPath)
{
if (_loadedAssets.ContainsKey(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;
// First, try the key exactly as provided. If it doesn't exist in the catalog,
// fall back to common project conventions (e.g. full Asset path).
foreach (var key in GetCandidateKeys(assetPath))
{
var locationsHandle = Addressables.LoadResourceLocationsAsync(key, typeof(TextAsset));
await locationsHandle.Task;
if (locationsHandle.Status != AsyncOperationStatus.Succeeded || locationsHandle.Result == null || locationsHandle.Result.Count == 0)
{
Addressables.Release(locationsHandle);
continue;
}
Addressables.Release(locationsHandle);
var handle = Addressables.LoadAssetAsync<TextAsset>(key);
await handle.Task;
if (handle.Status == AsyncOperationStatus.Succeeded && handle.Result != null)
{
_loadedTextAssets[assetPath] = handle;
return handle.Result;
}
// If load failed, release and try next candidate.
if (handle.IsValid())
{
Addressables.Release(handle);
}
}
BMLogger.LogError($"AddressableManager: No Location found for TextAsset key='{assetPath}'. " +
$"Tried: {string.Join(", ", GetCandidateKeys(assetPath).Select(k => $"'{k}'"))}");
LogSimilarKeys(assetPath);
return null;
}
catch (Exception e)
{
BMLogger.LogError(e.StackTrace);
BMLogger.LogError($"AddressableManager: Failed to load TextAsset '{assetPath}': {e}");
return null;
}
}
private static IEnumerable<string> GetCandidateKeys(string assetPath)
{
if (string.IsNullOrWhiteSpace(assetPath))
{
yield break;
}
// Exact key (what caller asked for)
yield return assetPath;
// Common fallback used by this repo's Addressables settings: full asset path address.
// Example in `Assets/AddressableAssetsData/AssetGroups/configuration.asset`:
// m_Address: Assets/Addressable/elements.txt
if (!assetPath.Contains("/") && !assetPath.Contains("\\"))
{
yield return $"Assets/Addressable/{assetPath}";
}
}
private static void LogSimilarKeys(string needle)
{
// Helpful diagnostics in dev builds: show a few keys containing the substring.
try
{
var lower = needle?.ToLowerInvariant();
if (string.IsNullOrEmpty(lower))
{
return;
}
const int max = 20;
var matches = new List<string>(max);
foreach (var locator in Addressables.ResourceLocators)
{
foreach (var keyObj in locator.Keys)
{
if (keyObj is not string keyStr)
{
continue;
}
if (!keyStr.ToLowerInvariant().Contains(lower))
{
continue;
}
matches.Add(keyStr);
if (matches.Count >= max)
{
goto Done;
}
}
}
Done:
if (matches.Count > 0)
{
BMLogger.LogWarning($"AddressableManager: Similar Addressables keys for '{needle}': {string.Join(", ", matches)}");
}
}
catch
{
// ignore diagnostics failures
}
}
/// <summary>
/// Load an asset asynchronously. The address should look like this: "models/npcs/npc/魅灵首领/魅灵首领/魅灵首领.prefab"
/// </summary>
@@ -321,7 +321,15 @@ namespace ModelRenderer.Scripts.GameData
// if (!File.Exists(pathname)) return -1;
var dataFile = await AddressableManager.Instance.LoadTextAssetAsync("elements.data");
// Addressables key must match the configured "Address". This repo currently uses full asset paths
// (see `Assets/AddressableAssetsData/AssetGroups/configuration.asset`).
// `AddressableManager.LoadTextAssetAsync` also has fallbacks, so "elements.txt" will work too.
var dataFile = await AddressableManager.Instance.LoadTextAssetAsync("Assets/Addressable/elements.txt");
if (dataFile == null)
{
BMLogger.LogError("ElementDataMan: Failed to load Addressable TextAsset for elements data.");
return -1;
}
using (var file = new MemoryStream(dataFile.bytes))
{