Files
zeling_v2/Docs/Standards/AddressablesLabelSpec.md
Joywayer c88d2d0549 feat: Addressables rules/sync tools, UI fixes, AddressKeys update
- Add AddressableRules.cs: single source of truth for prefix->group and prefix->label rules
- Add AddressableRuleSyncWindow.cs: scan/fix/export-CSV tool (BaseGames > Addressables > Rule Sync)
- AddressableBatchTool.cs: delegate DeriveGroupName to AddressableRules, remove duplicate PrefixGroupMap
- AddressKeys.cs: add Labels constants (Preload, Poolable, Enemy, BGM, SFX, Charms, Config, Weapon)
- Docs/Standards/AddressablesLabelSpec.md: new label naming & assignment spec
- Docs/Standards/AssetFolderSpec.md: update Addressables group strategy section
- SplashScreenController.cs: fix MainMenu loading flow
- BootFlowSetupWizard.cs / SceneScaffoldTools.cs: scene scaffold fixes
- PlayerInputActions: set UI/Point to Pass-Through type
- Persistent.unity: add BootSequencer to auto-load MainMenu on play
- EditorBuildSettings.asset: register scenes for build

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-20 11:10:31 +08:00

263 lines
10 KiB
Markdown
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.
# Addressables Label标签命名与使用规范
> **版本**1.0
> **创建日期**2026-05
> **适用范围**`Assets/_Game/` 目录下所有注册到 Addressables 的资产
> **关联文档**`Standards/AssetFolderSpec.md §8`、`Scripts/Core/Assets/AddressKeys.cs`
---
## 目录
1. [设计原则](#1-设计原则)
2. [Label 清单](#2-label-清单)
3. [每类资产的 Label 分配](#3-每类资产的-label-分配)
4. [AddressKeys.cs 常量对照](#4-addresskeyscs-常量对照)
5. [使用规范与禁止行为](#5-使用规范与禁止行为)
6. [新增 Label 决策流程](#6-新增-label-决策流程)
---
## 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. 在 Addressables Groups 窗口 → Label 列表中创建同名标签
3. 在本文档 §2 Label 清单中追加说明行
4. 在本文档 §3 对应资产类型的表格中标注
5. 运行 AddressKeyValidator 验证无遗漏
```