Files
zeling_v2/Assets/_Game/Scripts/Editor/Shared/AddressableRegistrar.cs
2026-06-08 16:05:00 +08:00

101 lines
4.6 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 UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
using UnityEngine;
namespace BaseGames.Editor
{
/// <summary>
/// 可复用的 Addressable 注册器:把资产登记到正确的分组并按规范打标。
///
/// 分组与标签均由 <see cref="AddressableRules"/> 推导(规范来源:
/// Docs/Standards/AddressablesLabelSpec.md §3 / AssetFolderSpec.md §8
/// 因此结果与 <c>AddressableManagerWindow</c>、<c>AddressKeyValidator</c> 完全一致。
///
/// 供各脚手架(如 <c>SceneObjectPlacerTool</c> 创建 Prefab 后)一键注册,
/// 避免每个工具重复实现 Addressables Settings API。
/// </summary>
public static class AddressableRegistrar
{
/// <summary>
/// 将指定路径的资产注册为 Addressable。
/// 地址默认取文件名(可用 <paramref name="addressOverride"/> 覆盖);
/// 分组与标签按 <see cref="AddressableRules"/> 推导,
/// <paramref name="extraLabels"/> 在规范标签之上追加(如 E003 幼蛭额外的 Poolable/Preload
/// </summary>
/// <returns>最终写入的地址Addressables 未初始化或资产不存在时返回 null。</returns>
public static string Register(string assetPath, string addressOverride = null,
IEnumerable<string> extraLabels = null, List<string> report = null)
{
var settings = AddressableAssetSettingsDefaultObject.Settings;
if (settings == null)
{
report?.Add("Addressable Asset Settings 不存在(未初始化),已跳过 Addressable 注册。");
return null;
}
string guid = AssetDatabase.AssetPathToGUID(assetPath);
if (string.IsNullOrEmpty(guid))
{
report?.Add($"资产不存在,无法注册 Addressable{assetPath}");
return null;
}
string address = string.IsNullOrEmpty(addressOverride)
? System.IO.Path.GetFileNameWithoutExtension(assetPath)
: addressOverride;
string groupName = AddressableRules.GetExpectedGroup(address);
var group = groupName != null ? EnsureGroup(settings, groupName) : settings.DefaultGroup;
var entry = settings.FindAssetEntry(guid)
?? settings.CreateOrMoveEntry(guid, group, false, false);
if (entry == null)
{
report?.Add($"创建 Addressable 条目失败:{assetPath}");
return null;
}
entry.address = address;
settings.MoveEntry(entry, group, false, false);
var labels = new HashSet<string>(AddressableRules.GetExpectedLabels(address));
if (extraLabels != null)
foreach (var l in extraLabels)
if (!string.IsNullOrWhiteSpace(l)) labels.Add(l);
foreach (var l in labels)
SetLabel(settings, entry, l);
settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryModified, entry, true);
report?.Add($"✅ Addressable 注册:{address} → 分组 {group.name}"
+ (labels.Count > 0 ? $",标签 [{string.Join(", ", labels.OrderBy(x => x))}]" : ",无标签"));
return address;
}
private static AddressableAssetGroup EnsureGroup(AddressableAssetSettings settings, string name)
{
var existing = settings.groups.FirstOrDefault(g => g != null && g.name == name);
if (existing != null) return existing;
var tmpl = settings.GroupTemplateObjects.FirstOrDefault() as AddressableAssetGroupTemplate;
var schemas = tmpl != null ? new List<AddressableAssetGroupSchema>(tmpl.SchemaObjects) : null;
var created = settings.CreateGroup(name, false, false, true, schemas);
if (created != null)
Debug.Log($"[AddressableRegistrar] 已自动创建分组:{name}");
return created ?? settings.DefaultGroup;
}
private static void SetLabel(AddressableAssetSettings settings, AddressableAssetEntry entry, string label)
{
if (!settings.GetLabels().Contains(label))
{
settings.AddLabel(label, true);
Debug.Log($"[AddressableRegistrar] 已创建标签:{label}");
}
entry.SetLabel(label, true, true);
}
}
}