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>
This commit is contained in:
262
Docs/Standards/AddressablesLabelSpec.md
Normal file
262
Docs/Standards/AddressablesLabelSpec.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# 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 验证无遗漏
|
||||
```
|
||||
@@ -512,16 +512,21 @@ Config/DifficultyEasy
|
||||
|
||||
### 8.3 Label(标签)使用规范
|
||||
|
||||
> 完整定义见 `Standards/AddressablesLabelSpec.md`。
|
||||
|
||||
| 标签 | 用途 | 相关常量 |
|
||||
|------|------|---------|
|
||||
| `Enemy` | 所有敌人 Prefab,用于 `LoadAssetsAsync` 批量实例化 | `AddressKeys.Labels.Enemy` |
|
||||
| `Poolable` | 纳入对象池管理的 Prefab(VFX、抛射物、收集物等)| `AddressKeys.Labels.Poolable` |
|
||||
| `BGM` | BGM 音频资源(FMOD bank 或 AudioClip) | `AddressKeys.Labels.BGM` |
|
||||
| `Charms` | 所有护身符 Prefab/SO,用于护身符列表加载 | `AddressKeys.Labels.Charms` |
|
||||
| `Preload` | 游戏启动时必须预加载的资产 | (待添加常量) |
|
||||
| `Preload` | 游戏启动时通过 `DownloadDependenciesAsync` 预热下载依赖 | `AddressKeys.Labels.Preload` |
|
||||
| `Poolable` | 纳入 `GlobalObjectPool` 对象池管理的 Prefab(VFX、投射物、收集物等)| `AddressKeys.Labels.Poolable` |
|
||||
| `Enemy` | 所有敌人 Prefab,用于区域 Spawner `LoadAssetsAsync` 批量加载 | `AddressKeys.Labels.Enemy` |
|
||||
| `BGM` | BGM 音频 AudioClip / FMOD bank 引用 SO | `AddressKeys.Labels.BGM` |
|
||||
| `SFX` | 音效 AudioClip / SFX 配置 SO | `AddressKeys.Labels.SFX` |
|
||||
| `Charms` | 所有护身符配置 SO,供 EquipmentManager 批量加载列表 | `AddressKeys.Labels.Charms` |
|
||||
| `Config` | 运行时动态加载的配置类 SO | `AddressKeys.Labels.Config` |
|
||||
| `Weapon` | 所有武器 Prefab,玩家换形态时批量加载 | `AddressKeys.Labels.Weapon` |
|
||||
|
||||
- 一个资产可附加多个标签(例如 `VFX_HitSpark` 同时有 `Poolable` 标签)
|
||||
- 新增标签前确认是否有批量加载的需求,避免标签膨胀
|
||||
- 一个资产可附加多个标签(例如 `VFX_HitSpark` 同时有 `Poolable` 和 `Preload` 标签)
|
||||
- 新增标签前确认是否有批量加载的实际需求,避免标签膨胀(决策流程见 `AddressablesLabelSpec.md §6`)
|
||||
|
||||
### 8.4 AddressKeys.cs 维护流程
|
||||
|
||||
|
||||
Reference in New Issue
Block a user