CultLib/src/GameCult.Caching/CultAssetGuidKey.cs
Meta Vens 1e398e0116 Studio: read and write sub-asset Addressables keys, warn on stale values
Ruling S (2026-09-17): a stored [CultInspectorAssetGuid] value is the
Addressables key form itself, the bare GUID for a main asset or
"guid[subAssetName]" for a picked sub-asset (one sprite of a sheet, say) -
the same shape AssetReference keeps and Addressables.LoadAssetAsync<T>
accepts.

CultAssetGuidKey (engine-free, GameCult.Caching) pins the parse/format rule
with unit tests (bare guid, guid[name], names with brackets/spaces,
malformed input), so headless checks can share it without touching Unity.

The Studio drawer's AssetGuid branch now: resolves either key form on read;
refuses to store a built-in resource's GUID (it has no Addressables entry)
and logs why instead of silently writing nothing; shows a warning next to a
stored value that fails to parse or resolve instead of drawing it as an
ordinary empty field, and never rewrites that stale value on its own.

Rebuilt GameCult.Caching/GameCult.Caching.MessagePack plugin DLLs
(scripts/build-unity-package.ps1 -UpdateTemplate) since the new type ships
in GameCult.Caching. Compiled CultCacheStudioDrawers.cs and
CultCacheStudioWindow.cs against Unity 6000.3.24f1's editor reference set
plus these plugins in a scratch csproj (removed after): 0 errors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 19:48:45 +02:00

39 lines
1.4 KiB
C#

#nullable enable
namespace GameCult.Caching
{
// The Addressables key form a [CultInspectorAssetGuid] member stores: the bare GUID for a main
// asset, or "guid[subAssetName]" when a sub-asset (one sprite of a sheet, say) is picked. This is
// Addressables' own key shape (what AssetReference keeps as GUID plus sub-object name); engine-free
// so both the Studio drawer and any headless check can pin the same parse without touching Unity.
public static class CultAssetGuidKey
{
public static bool TryParse(string key, out string guid, out string? subAssetName)
{
guid = string.Empty;
subAssetName = null;
if (string.IsNullOrEmpty(key)) return false;
var bracket = key.IndexOf('[');
if (bracket < 0)
{
guid = key;
return true;
}
if (bracket == 0 || key[key.Length - 1] != ']') return false;
var name = key.Substring(bracket + 1, key.Length - bracket - 2);
if (name.Length == 0) return false;
guid = key.Substring(0, bracket);
subAssetName = name;
return true;
}
public static string Format(string guid, string? subAssetName)
{
guid ??= string.Empty;
return string.IsNullOrEmpty(subAssetName) ? guid : guid + "[" + subAssetName + "]";
}
}
}