AssetFolderSpec.md:
- §8.1: Enemies_{Region} → Enemies (match AddressableRules.cs single group)
- §8.4: fix old menu paths (Tools/Verification → Addressables)
- §10.3: fix Skill SO path (Data/Player/Skills → Data/Progression/Skills)
- §10.4: Charm workflow — remove 'bypass editor tools' recommendation
- §3.2: add SPL_ prefix for SpellSO
- Bump to v1.2
AddressablesLabelSpec.md:
- §6 step 7: fix old Verification menu path
- §7.2/7.3/7.4: unify menu notation (→ to /) and fix old Tools/Verification paths
- Bump to v1.2
AddressKeys.cs:
- Remove duplicate <summary> XML doc comment in Labels class
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
318 lines
13 KiB
Markdown
318 lines
13 KiB
Markdown
# Addressables Label(标签)命名与使用规范
|
||
|
||
> **版本**:1.2
|
||
> **创建日期**:2026-05
|
||
> **适用范围**:`Assets/_Game/` 目录下所有注册到 Addressables 的资产
|
||
> **关联文档**:`Standards/AssetFolderSpec.md §8`、`Scripts/Core/Assets/AddressKeys.cs`、`Scripts/Editor/Addressables/AddressableRules.cs`
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [设计原则](#1-设计原则)
|
||
2. [Label 清单](#2-label-清单)
|
||
3. [每类资产的 Label 分配](#3-每类资产的-label-分配)
|
||
4. [AddressKeys.cs 常量对照](#4-addresskeyscs-常量对照)
|
||
5. [使用规范与禁止行为](#5-使用规范与禁止行为)
|
||
6. [新增 Label 决策流程](#6-新增-label-决策流程)
|
||
7. [工具链与自动化](#7-工具链与自动化)
|
||
|
||
---
|
||
|
||
## 1. 设计原则
|
||
|
||
### 1.1 Label 的作用
|
||
|
||
Addressable **Label** 是为"需要按类别批量操作"而设计的:
|
||
|
||
- **批量下载依赖**(BootSequencer 预热)
|
||
- **批量加载资产列表**(`Addressables.LoadAssetsAsync<T>(label, ...)`)
|
||
- **构建分析/验证工具**筛选特定类别的资产
|
||
|
||
> **Label ≠ Group。** Group 决定打包策略(打入哪个 bundle、何时加载卸载);Label 决定运行时如何批量引用。一个资产可同时属于某 Group 且带有多个 Label。
|
||
|
||
### 1.2 Label 命名格式
|
||
|
||
```
|
||
PascalCase,不加前缀,英文单词或词组
|
||
```
|
||
|
||
- ✅ `Poolable`、`Preload`、`Enemy`
|
||
- ❌ `lbl_poolable`、`POOLABLE`、`可对象池`
|
||
|
||
### 1.3 Label 膨胀控制
|
||
|
||
新增 Label 前必须满足**至少一条**:
|
||
|
||
1. 有代码通过该 Label 进行 **批量异步加载**(`LoadAssetsAsync`)
|
||
2. 有 **BootSequencer 预热需求**(`DownloadDependenciesAsync`)
|
||
3. 有 **编辑器工具**需要按 Label 筛选/校验资产
|
||
|
||
纯用于分类记录但代码不引用的标签,**不得创建**——用文件夹路径或 Group 命名代替。
|
||
|
||
---
|
||
|
||
## 2. Label 清单
|
||
|
||
| Label | 代码常量 | 用途 | 使用者 |
|
||
|-------|---------|------|--------|
|
||
| `Preload` | `AddressKeys.Labels.Preload` | 游戏启动时通过 `DownloadDependenciesAsync` 预热下载依赖。涵盖所有首帧可能用到的资产。 | `BootSequencer` |
|
||
| `Poolable` | `AddressKeys.Labels.Poolable` | 纳入 `GlobalObjectPool` 管理的 Prefab。标记此标签意味着该资产**必须**在 `GlobalObjectPool._warmupConfigs` 中配置初始池数量。 | `GlobalObjectPool`、`AddressKeyValidator` |
|
||
| `Enemy` | `AddressKeys.Labels.Enemy` | 所有敌人顶级 Prefab。用于区域 Spawner 通过 `LoadAssetsAsync<GameObject>(Labels.Enemy, ...)` 批量加载该区域敌人,或工具统计敌人总数。 | 区域 EnemySpawner(待实现) |
|
||
| `BGM` | `AddressKeys.Labels.BGM` | 背景音乐 AudioClip 或 FMOD bank 引用 SO。`AudioManager` 通过此标签批量加载 BGM 目录,按 ID 播放。 | `AudioManager` |
|
||
| `SFX` | `AddressKeys.Labels.SFX` | 音效 AudioClip 或 SFX 配置 SO。与 `BGM` 平行,供 `AudioManager` 批量建立 SFX 索引。 | `AudioManager` |
|
||
| `Charms` | `AddressKeys.Labels.Charms` | 所有护身符配置 SO(`CHM_*.asset`)。`EquipmentManager` / 护身符选择 UI 通过此标签加载完整护身符列表,无需逐一引用。 | `EquipmentManager`、护身符选择界面 |
|
||
| `Config` | `AddressKeys.Labels.Config` | 运行时**动态加载**的配置类 SO(如 `Config/FootstepCatalog`)。**静态引用**(Inspector 直接拖拽)的 SO 不加此标签。 | `AssetLoader`、各需要延迟加载配置的系统 |
|
||
| `Weapon` | `AddressKeys.Labels.Weapon` | 所有武器 Prefab(`WPN_*.prefab`)。玩家换形态时通过此标签加载对应武器列表,避免硬编码每把武器地址。 | `PlayerFormController`(待实现) |
|
||
|
||
---
|
||
|
||
## 3. 每类资产的 Label 分配
|
||
|
||
### 3.1 场景(Scenes)
|
||
|
||
| Address | 所在 Group | Labels |
|
||
|---------|-----------|--------|
|
||
| `Scene_Persistent` | `Scenes` | ——(常驻,无需 Label) |
|
||
| `Scene_MainMenu` | `Scenes` | `Preload` |
|
||
| `Room_{Region}_{nn}` | `Room_{Region}` | ——(区域加载时整组载入) |
|
||
| `Boss_{Name}` | `Boss_{Name}` | ——(Boss 战前整组载入) |
|
||
|
||
> 测试专用场景(`Scenes/Testings/`)**不注册 Addressable**,不分配任何 Label。
|
||
|
||
---
|
||
|
||
### 3.2 玩家(Player)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `PLY_Player` | `Preload` | 玩家 Prefab 在进入 Gameplay 前必须就绪 |
|
||
|
||
---
|
||
|
||
### 3.3 敌人(Enemies)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `ENM_GruntWarrior` | `Enemy` | 无 `Preload`:区域加载时按需拉取 |
|
||
| `ENM_SkullArcher` | `Enemy` | 同上 |
|
||
| 新增敌人 `ENM_{Name}` | `Enemy` | 所有敌人必须加此 Label |
|
||
|
||
> 高频召唤的敌人(每关必出现)可**额外加 `Preload`** 参与启动预热。
|
||
|
||
---
|
||
|
||
### 3.4 投射物(Projectiles)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `PROJ_Arrow` | `Poolable`, `Preload` | 对象池 + 启动预热 |
|
||
| `PROJ_Fireball` | `Poolable`, `Preload` | 同上 |
|
||
| `PROJ_SoulBall` | `Poolable`, `Preload` | 同上 |
|
||
| 新增 `PROJ_{Name}` | `Poolable`, `Preload` | 默认双标签 |
|
||
|
||
---
|
||
|
||
### 3.5 特效(VFX)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `VFX_HitSpark` | `Poolable`, `Preload` | 命中特效,高频使用 |
|
||
| `VFX_BloodSplat` | `Poolable`, `Preload` | 同上 |
|
||
| `VFX_Explosion` | `Poolable`, `Preload` | 同上 |
|
||
| 新增通用 VFX | `Poolable`, `Preload` | 高频共用特效默认双标签 |
|
||
| 区域专属 VFX | `Poolable` | 仅 `Poolable`,不加 `Preload`(区域加载时预热) |
|
||
|
||
---
|
||
|
||
### 3.6 UI Prefab
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `UI_FloatingDamageText` | `Poolable`, `Preload` | 对象池 Prefab,战斗中高频出现 |
|
||
| 其余 UI 面板 `UI_{Name}` | ——(或 `Preload`) | 按需加载;全局常驻面板加 `Preload` |
|
||
|
||
---
|
||
|
||
### 3.7 收集物(Collectibles)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `COL_LingZhu` | `Poolable`, `Preload` | 灵珠,战斗中高频掉落 |
|
||
| `COL_Item` | `Poolable`, `Preload` | 道具掉落 |
|
||
| `COL_HPOrb` | `Poolable`, `Preload` | 血球,战斗中高频掉落 |
|
||
| 新增 `COL_{Name}` | `Poolable`, `Preload` | 默认双标签 |
|
||
|
||
---
|
||
|
||
### 3.8 武器(Weapons)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `WPN_SkyBlade` | `Weapon`, `Preload` | 默认形态武器,启动时预热 |
|
||
| `WPN_EarthClaw` | `Weapon`, `Preload` | 同上 |
|
||
| `WPN_SoulStaff` | `Weapon`, `Preload` | 同上 |
|
||
| 新增 `WPN_{Name}` | `Weapon` | 是否加 `Preload` 视形态是否为默认形态 |
|
||
|
||
---
|
||
|
||
### 3.9 护身符(Charms)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `CHM_{Name}` | `Charms` | 所有护身符 SO 统一加此标签,供 EquipmentManager 批量加载 |
|
||
|
||
> 护身符 SO 不加 `Preload`——玩家进入装备界面时再批量拉取,不影响启动速度。
|
||
|
||
---
|
||
|
||
### 3.10 配置数据(Config)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| `Config/FootstepCatalog` | `Config`, `Preload` | 脚步音频目录,Gameplay 开始前必须就绪 |
|
||
| 新增 `Config/{Name}` | `Config` | 是否加 `Preload` 视是否在 Gameplay 首帧使用 |
|
||
|
||
---
|
||
|
||
### 3.11 音频(Audio)
|
||
|
||
| Address | Labels | 说明 |
|
||
|---------|--------|------|
|
||
| BGM 资源 `AUD_BGM_{Name}` | `BGM` | AudioManager 批量建立 BGM 索引 |
|
||
| SFX 资源 `AUD_SFX_{Name}` | `SFX` | AudioManager 批量建立 SFX 索引 |
|
||
|
||
> 音频资源不加 `Preload`——由 AudioManager 在 BGM 播放前异步流式加载。
|
||
|
||
---
|
||
|
||
## 4. AddressKeys.cs 常量对照
|
||
|
||
代码中使用 Label 时,**禁止硬编码字符串**,统一引用 `AddressKeys.Labels` 内的常量:
|
||
|
||
```csharp
|
||
// ✅ 正确
|
||
await Addressables.DownloadDependenciesAsync(AddressKeys.Labels.Preload, false);
|
||
var enemies = await Addressables.LoadAssetsAsync<GameObject>(AddressKeys.Labels.Enemy, null);
|
||
|
||
// ❌ 禁止
|
||
await Addressables.DownloadDependenciesAsync("Preload", false);
|
||
```
|
||
|
||
当前 `AddressKeys.Labels` 完整清单:
|
||
|
||
| 常量 | 字符串值 |
|
||
|------|---------|
|
||
| `AddressKeys.Labels.Preload` | `"Preload"` |
|
||
| `AddressKeys.Labels.Poolable` | `"Poolable"` |
|
||
| `AddressKeys.Labels.Enemy` | `"Enemy"` |
|
||
| `AddressKeys.Labels.BGM` | `"BGM"` |
|
||
| `AddressKeys.Labels.SFX` | `"SFX"` |
|
||
| `AddressKeys.Labels.Charms` | `"Charms"` |
|
||
| `AddressKeys.Labels.Config` | `"Config"` |
|
||
| `AddressKeys.Labels.Weapon` | `"Weapon"` |
|
||
|
||
> 每次新增 Label 常量,同步在 Addressables Groups 窗口中创建同名标签,并在此文档 §2 增加说明行。
|
||
|
||
---
|
||
|
||
## 5. 使用规范与禁止行为
|
||
|
||
### 5.1 多标签组合规则
|
||
|
||
一个资产可同时附加多个 Label,组合语义如下:
|
||
|
||
| 组合 | 含义 |
|
||
|------|------|
|
||
| `Poolable` + `Preload` | 启动预热依赖 + 纳入对象池,适用于高频 VFX、投射物、收集物 |
|
||
| `Enemy` + `Preload` | 高频召唤敌人,启动时下载依赖(实例化仍由 Spawner 按需触发) |
|
||
| `Config` + `Preload` | 首帧必须可用的配置 SO |
|
||
| `Charms` 单独 | 进入装备界面时才批量加载,不参与启动预热 |
|
||
|
||
### 5.2 禁止行为
|
||
|
||
| 禁止 | 原因 |
|
||
|------|------|
|
||
| 给 **ScriptableObject 事件频道**(`EVT_*.asset`)加任何 Label | 事件频道通过 Inspector 直接引用,不走 Addressables |
|
||
| 给 **子 Prefab**(HitBox、HurtBox、骨骼节点)加任何 Label | 子对象不单独注册 Addressable |
|
||
| 给 **Atlas**(`.spriteatlas`)加任何 Label | Atlas 由 Prefab/Material 间接引用,无需 Label |
|
||
| 给 **Shader / Material** 加任何 Label | 随 Prefab 打包,无独立 Label 需求 |
|
||
| 给 **测试场景**(`Scenes/Testings/`)加任何 Label | 不进入 Addressables,不可加 Label |
|
||
| 代码中直接写字符串 Label(如 `"Poolable"`) | 必须用 `AddressKeys.Labels.Poolable` 常量 |
|
||
|
||
---
|
||
|
||
## 6. 新增 Label 决策流程
|
||
|
||
```
|
||
需要新增 Label?
|
||
├── 是否有代码通过该 Label 执行 LoadAssetsAsync?
|
||
│ ├── 是 → 可新增
|
||
│ └── 否 → 是否为 BootSequencer 预热需求?
|
||
│ ├── 是 → 可新增(并入 Preload,不新建)
|
||
│ └── 否 → 是否为编辑器验证工具需求?
|
||
│ ├── 是 → 可新增(文档注明仅供工具使用)
|
||
│ └── 否 → ❌ 不允许新增(用 Group 或文件夹替代)
|
||
│
|
||
新增 Label 的执行步骤:
|
||
1. 在 AddressKeys.Labels 类中添加 public const string {Name} = "{Name}";
|
||
2. 在 AddressableRules.cs 的 PrefixLabelMap / ExactLabelMap 中添加对应映射规则
|
||
3. 在 Addressables Groups 窗口 → Label 列表中创建同名标签
|
||
4. 在本文档 §2 Label 清单中追加说明行
|
||
5. 在本文档 §3 对应资产类型的表格中标注
|
||
6. 运行 Rule Sync(菜单 BaseGames → Addressables → Rule Sync)Scan 验证无遗漏
|
||
7. 运行 AddressKeyValidator(菜单 `BaseGames/Addressables/Validate Address Keys`)确认
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 工具链与自动化
|
||
|
||
### 7.1 规则权威来源
|
||
|
||
所有分组与标签的映射规则**集中定义**于:
|
||
|
||
```
|
||
Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs
|
||
```
|
||
|
||
- `PrefixGroupMap` — 地址前缀 → Group 名称
|
||
- `PrefixLabelMap` — 地址前缀 → Label 列表(更具体的前缀排在前面)
|
||
- `ExactLabelMap` — 精确地址 → Label 列表(覆盖前缀规则的特殊情况)
|
||
|
||
**修改规则时只改 `AddressableRules.cs` 一处**,两个工具(`AddressableBatchTool` 和 `AddressableRuleSyncWindow`)均从此处读取,保证一致性。
|
||
|
||
### 7.2 日常标签维护工作流
|
||
|
||
```
|
||
新建/更新资产后:
|
||
1. 打开 Rule Sync 窗口(菜单 `BaseGames/Addressables/Rule Sync`)
|
||
2. 点击 [Scan All] — 扫描所有 Addressable 条目与期望规则的差异
|
||
3. 查看报告:
|
||
- Group Mismatch — 资产在错误的分组
|
||
- Label Missing — 缺少应有标签
|
||
- Label Extra — 存在不应有的标签
|
||
4. 点击 [Fix All] 或逐条点击 [Fix] 自动修复
|
||
5. 可选:点击 [Export CSV] 导出差异报告存档
|
||
6. 运行 Validate Address Keys 做最终验证
|
||
```
|
||
|
||
### 7.3 批量注册工作流(新增大量资产)
|
||
|
||
```
|
||
1. 将资产按命名前缀放置到正确目录(见 AssetFolderSpec.md §2–§4)
|
||
2. 打开 Addressable Batch Tool(菜单 `BaseGames/Addressables/Addressable Batch Tool`)
|
||
3. 切换到 "② 文件夹批量" 标签,选择目标文件夹,点击 [Register Folder]
|
||
4. 切换到 "① 同步 AddressKeys" 标签,点击 [Scan],为新注册的资产补充 AddressKeys.cs 常量
|
||
5. 返回 Rule Sync 窗口执行 Scan → Fix All 统一校正 Group / Label
|
||
6. 运行 Validate Address Keys 验证
|
||
```
|
||
|
||
### 7.4 工具一览
|
||
|
||
| 工具 | 菜单路径 | 核心功能 |
|
||
|------|---------|---------|
|
||
| **Rule Sync** | `BaseGames/Addressables/Rule Sync` | 扫描 + 修复分组/标签不合规条目;导出 CSV |
|
||
| **Addressable Batch Tool** | `BaseGames/Addressables/Addressable Batch Tool` | 三标签:AddressKeys 同步 / 文件夹批量注册 / Selection 注册 |
|
||
| **Validate Address Keys** | `BaseGames/Addressables/Validate Address Keys` | 验证 AddressKeys.cs 所有常量均已在 Addressables 注册,构建前自动触发 |
|