diff --git a/Assets/_Game/Scenes/Persistent.unity b/Assets/_Game/Scenes/Persistent.unity
index 60c8d7b..f573507 100644
--- a/Assets/_Game/Scenes/Persistent.unity
+++ b/Assets/_Game/Scenes/Persistent.unity
@@ -922,14 +922,14 @@ MonoBehaviour:
DefaultMode: 2
DefaultBlend:
Style: 1
- Time: 2
+ Time: 1
CustomCurve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
- CustomBlends: {fileID: 0}
+ CustomBlends: {fileID: 11400000, guid: 9906ca91115b34d498a040782ef36e92, type: 2}
--- !u!81 &464414703
AudioListener:
m_ObjectHideFlags: 0
@@ -971,7 +971,7 @@ Camera:
height: 1
near clip plane: 0.1
far clip plane: 5000
- field of view: 40
+ field of view: 10
orthographic: 0
orthographic size: 10
m_Depth: 0
@@ -998,7 +998,7 @@ Transform:
m_GameObject: {fileID: 464414701}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
- m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalPosition: {x: -18.954266, y: 5.5, z: -64}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
diff --git a/Assets/_Game/Scenes/Testings/TestRoomA.unity b/Assets/_Game/Scenes/Testings/TestRoomA.unity
index 3bc3459..6fac123 100644
--- a/Assets/_Game/Scenes/Testings/TestRoomA.unity
+++ b/Assets/_Game/Scenes/Testings/TestRoomA.unity
@@ -4304,6 +4304,7 @@ Transform:
m_Children:
- {fileID: 1351863799}
- {fileID: 1484423199}
+ - {fileID: 2035265042}
m_Father: {fileID: 783576435}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &200829413
@@ -21980,7 +21981,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
- m_IsActive: 1
+ m_IsActive: 0
--- !u!61 &1354690326
BoxCollider2D:
m_ObjectHideFlags: 0
@@ -26723,6 +26724,63 @@ Transform:
- {fileID: 67436266}
m_Father: {fileID: 1076068180}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1001 &1627895894
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ serializedVersion: 3
+ m_TransformParent: {fileID: 199785320}
+ m_Modifications:
+ - target: {fileID: 5652501251207193424, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_Name
+ value: Sprite01
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalPosition.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalRotation.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalRotation.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalRotation.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ m_RemovedComponents: []
+ m_RemovedGameObjects: []
+ m_AddedGameObjects: []
+ m_AddedComponents: []
+ m_SourcePrefab: {fileID: 100100000, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
--- !u!1 &1628373459
GameObject:
m_ObjectHideFlags: 0
@@ -29564,8 +29622,8 @@ PolygonCollider2D:
- {x: -8, y: -2}
- {x: -11.5, y: -7}
- {x: 14, y: -7}
- - {x: 24.5, y: 5}
- {x: 14, y: 5}
+ - {x: 24.5, y: 5}
- {x: 24.5, y: 10}
- {x: -8, y: 10}
m_UseDelaunayMesh: 0
@@ -29925,7 +29983,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
- m_IsActive: 1
+ m_IsActive: 0
--- !u!61 &1865796629
BoxCollider2D:
m_ObjectHideFlags: 0
@@ -33076,6 +33134,11 @@ Transform:
m_Children: []
m_Father: {fileID: 2018245865}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &2035265042 stripped
+Transform:
+ m_CorrespondingSourceObject: {fileID: 7501110767542530711, guid: e9d9216d17e7b684096c94e8c347d46f, type: 3}
+ m_PrefabInstance: {fileID: 1627895894}
+ m_PrefabAsset: {fileID: 0}
--- !u!1 &2043241451
GameObject:
m_ObjectHideFlags: 0
diff --git a/Assets/_Game/Scripts/Core/Assets/AddressKeys.cs b/Assets/_Game/Scripts/Core/Assets/AddressKeys.cs
index 963f4da..96380db 100644
--- a/Assets/_Game/Scripts/Core/Assets/AddressKeys.cs
+++ b/Assets/_Game/Scripts/Core/Assets/AddressKeys.cs
@@ -53,13 +53,10 @@ namespace BaseGames.Core.Assets
// ── Config ScriptableObjects ─────────────────────────────────────
public const string DataFootstepCatalog = "Config/FootstepCatalog";
- ///
- /// Addressable 标签常量(用于批量加载)。
- /// 注意:这里是标签名称而非资产地址,不会被 AddressKeyValidator 校验。
- ///
///
/// Addressable Label 常量(用于批量加载与预热)。
/// 代码中引用 Label 时必须使用此处的常量,禁止硬编码字符串。
+ /// 注意:这里是标签名称而非资产地址,不会被 AddressKeyValidator 校验。
/// 完整说明见 Docs/Standards/AddressablesLabelSpec.md。
///
public static class Labels
diff --git a/Docs/Standards/AddressablesLabelSpec.md b/Docs/Standards/AddressablesLabelSpec.md
index 283a333..aed1f5d 100644
--- a/Docs/Standards/AddressablesLabelSpec.md
+++ b/Docs/Standards/AddressablesLabelSpec.md
@@ -1,6 +1,6 @@
# Addressables Label(标签)命名与使用规范
-> **版本**:1.1
+> **版本**:1.2
> **创建日期**:2026-05
> **适用范围**:`Assets/_Game/` 目录下所有注册到 Addressables 的资产
> **关联文档**:`Standards/AssetFolderSpec.md §8`、`Scripts/Core/Assets/AddressKeys.cs`、`Scripts/Editor/Addressables/AddressableRules.cs`
@@ -261,7 +261,7 @@ await Addressables.DownloadDependenciesAsync("Preload", false);
4. 在本文档 §2 Label 清单中追加说明行
5. 在本文档 §3 对应资产类型的表格中标注
6. 运行 Rule Sync(菜单 BaseGames → Addressables → Rule Sync)Scan 验证无遗漏
- 7. 运行 AddressKeyValidator(菜单 BaseGames → Verification → Validate Address Keys)确认
+ 7. 运行 AddressKeyValidator(菜单 `BaseGames/Addressables/Validate Address Keys`)确认
```
---
@@ -286,7 +286,7 @@ Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs
```
新建/更新资产后:
- 1. 打开 Rule Sync 窗口(菜单 BaseGames → Addressables → Rule Sync)
+ 1. 打开 Rule Sync 窗口(菜单 `BaseGames/Addressables/Rule Sync`)
2. 点击 [Scan All] — 扫描所有 Addressable 条目与期望规则的差异
3. 查看报告:
- Group Mismatch — 资产在错误的分组
@@ -301,7 +301,7 @@ Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs
```
1. 将资产按命名前缀放置到正确目录(见 AssetFolderSpec.md §2–§4)
- 2. 打开 Addressable Batch Tool(菜单 BaseGames → Tools → Addressable Batch Tool)
+ 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
@@ -312,6 +312,6 @@ Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs
| 工具 | 菜单路径 | 核心功能 |
|------|---------|---------|
-| **Rule Sync** | `BaseGames → Addressables → Rule Sync` | 扫描 + 修复分组/标签不合规条目;导出 CSV |
-| **Addressable Batch Tool** | `BaseGames → Tools → Addressable Batch Tool` | 三标签:AddressKeys 同步 / 文件夹批量注册 / Selection 注册 |
-| **Validate Address Keys** | `BaseGames → Verification → Validate Address Keys` | 验证 AddressKeys.cs 所有常量均已在 Addressables 注册,构建前自动触发 |
+| **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 注册,构建前自动触发 |
diff --git a/Docs/Standards/AssetFolderSpec.md b/Docs/Standards/AssetFolderSpec.md
index bc7fb8a..638e45e 100644
--- a/Docs/Standards/AssetFolderSpec.md
+++ b/Docs/Standards/AssetFolderSpec.md
@@ -1,6 +1,6 @@
# 资源文件夹目录规划与管理规范
-> **版本**:1.1
+> **版本**:1.2
> **创建日期**:2026-05
> **适用范围**:`Assets/` 目录下所有非代码资源(美术、数据、预制体、场景等)
> **资源管理系统**:Unity Addressables(禁止使用 `Resources.Load`)
@@ -274,6 +274,7 @@ Data/
| `ENM_` | 敌人 | `ENM_E001_Stats.asset` |
| `WPN_` | 武器 | `WPN_SkyBlade.asset` |
| `SKL_` | 技能/法术 | `SKL_SoulBlade.asset` |
+| `SPL_` | 法术(Spell) | `SPL_Fireball.asset` |
| `CHM_` | 护身符 | `CHM_GhostMantis.asset` |
| `SHP_` | 商店 | `SHP_Inventory_Forest.asset` |
| `MAP_` | 地图 | `MAP_RoomData_Forest_01.asset` |
@@ -472,7 +473,7 @@ UI Toolkit/
| `VFX_Common` | 通用高频特效(HitSpark、BloodSplat 等) | Local | 启动时预加载 |
| `Collectibles` | 收集物 Prefab(Geo、Item、HPOrb) | Local | 启动时预加载 |
| `Projectiles` | 抛射物 Prefab | Local | 启动时预加载 |
-| `Enemies_{Region}` | 该区域的敌人 Prefab | Local | 进入区域时加载 |
+| `Enemies` | 所有敌人 Prefab(`ENM_*`) | Local | 进入区域时加载 |
| `Room_{Region}` | 该区域的关卡场景 + 区域专属资产 | Local | 进入区域时加载 |
| `Boss_{Name}` | Boss 专属 Prefab + 场景 | Local | Boss 战开始前加载 |
| `Audio_Music` | BGM 音频(FMOD bank 引用) | Remote(可选)| 按需流式加载 |
@@ -538,11 +539,11 @@ Config/DifficultyEasy
```
1. 在 Project 中创建/导入资产
2. 在 AddressKeys.cs 中添加对应 const 字符串
-3. 在 AddressableBatchTool(菜单 BaseGames → Tools → Addressable Batch Tool)中:
+3. 在 AddressableBatchTool(菜单 `BaseGames/Addressables/Addressable Batch Tool`)中:
a. 切换到 "① 同步 AddressKeys" 标签
b. 点击 "Scan" 找到未注册的 Key
c. 选择目标 Group,点击 "Register" 完成注册
-4. 运行 AddressKeyValidator(菜单 BaseGames → Verification → Validate Address Keys)
+4. 运行 AddressKeyValidator(菜单 `BaseGames/Addressables/Validate Address Keys`)
确认无 Missing / Mismatch 警告
5. 提交 AddressKeys.cs 和 AddressableAssetSettings.asset 的修改
```
@@ -683,7 +684,7 @@ var (prefab, _) = await AssetLoader.LoadAsync(AddressKeys.PrefabPlay
```
1. 在 _Game/Art/Characters/Player/{FormID}/Animations/ 下创建技能动画片段(.anim)
2. 在 Skill Editor(菜单 BaseGames/Data/Skill Editor)左栏 [New] 创建 SKL_{SkillID}_Data.asset
- - 路径:_Game/Data/Player/Skills/SKL_{SkillID}_Data.asset
+ - 路径:`_Game/Data/Progression/Skills/SKL_{SkillID}_Data.asset`
- 命名:SKL_{SkillID}(示例:SKL_DashSlash、SKL_SpiritWave)
3. 使用 Skill HitBox Wizard(菜单 BaseGames/Create/Skill HitBox Prefab)生成
_Game/Prefabs/Skills/SKL_{SkillID}_HitBox.prefab(支持多段伤害配置)
@@ -693,10 +694,11 @@ var (prefab, _) = await AssetLoader.LoadAsync(AddressKeys.PrefabPlay
### 10.4 新增护身符(Charm)
-> **推荐工具**:直接在 Project 窗口 Create → 对应 CharmSO,然后通过 CharmSOEditor(Custom Inspector)配置效果类型与参数。
+> **推荐工具**:`BaseGames → Data → Character Wizard`(切换到 Charm 标签)或直接在 Project 窗口 右键 → Create,使用 `CharmSOEditor`(Custom Inspector)配置,**必须确保路径为 `_Game/Data/Progression/Charms/`,命名为 `CHM_{Name}.asset`**;若护身符类型较多,建议在 §12 中增加专属 Charm Editor 入口以强制规范。
```
-1. 在 _Game/Data/Progression/Charms/ 下创建 CHM_{Name}.asset(CharmSO)
+1. 使用 Character Wizard(菜单 BaseGames/Data/Character Wizard → Charm 标签)创建 CHM_{Name}.asset
+ - 路径:_Game/Data/Progression/Charms/CHM_{Name}.asset
- 命名:CHM_{Name}(示例:CHM_SoulReaper、CHM_IronSkin)
2. 在 Inspector 中通过 CharmSOEditor 下拉选择效果类型并配置参数
3. 在 AddressKeys.cs 中添加 DataCharm{Name} 常量