- Created a new markdown file detailing the configuration of InputDeviceIconSetSO. - Included sections on system architecture, field explanations, image specifications, and complete workflow from setup to runtime. - Documented the automatic device recognition logic and provided troubleshooting for common issues. - Added references to relevant files and scripts for easier navigation.
907 lines
52 KiB
Markdown
907 lines
52 KiB
Markdown
# 资源文件夹目录规划与管理规范
|
||
|
||
> **版本**:1.3
|
||
> **创建日期**:2026-05
|
||
> **适用范围**:`Assets/` 目录下所有非代码资源(美术、数据、预制体、场景等)
|
||
> **资源管理系统**:Unity Addressables(禁止使用 `Resources.Load`)
|
||
> **关联文档**:`Architecture/01_ProjectStructure.md`、`Architecture/13_AssetPoolModule.md`
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [为什么使用 `_Game/` 父目录](#0-为什么使用-_game-父目录)
|
||
2. [整体目录结构总览](#1-整体目录结构总览)
|
||
3. [Art/ 美术资源规范](#2-art-美术资源规范)
|
||
4. [Data/ ScriptableObject 规范](#3-data-scriptableobject-规范)
|
||
5. [Prefabs/ 预制体规范](#4-prefabs-预制体规范)
|
||
6. [Scenes/ 场景规范](#5-scenes-场景规范)
|
||
7. [Shaders/ 着色器规范](#6-shaders-着色器规范)
|
||
8. [UI Toolkit/ 规范](#7-ui-toolkit-规范)
|
||
9. [Addressables 管理规范](#8-addressables-管理规范)
|
||
10. [Import Settings 规范](#9-import-settings-规范)
|
||
11. [资源新增工作流](#10-资源新增工作流)
|
||
12. [禁止行为清单](#11-禁止行为清单)
|
||
13. [编辑器工具参考](#12-编辑器工具参考)
|
||
|
||
---
|
||
|
||
## 0. 为什么使用 `_Game/` 父目录
|
||
|
||
### 核心矛盾
|
||
|
||
Unity 项目的 `Assets/` 根目录通常同时存放**第一方游戏内容**和**第三方插件目录**。两者混杂会导致:
|
||
|
||
- Project 窗口难以快速定位自有资产(需要在 `Art/`、`Feel/`、`Opsive/` 之间来回跳转)
|
||
- 插件升级时不清楚哪些目录是项目本身的
|
||
- 构建分析工具(如 Addressables Analyze、Build Layout)的输出路径噪音多
|
||
|
||
### 解决方案:`_Game/` 父目录
|
||
|
||
将**所有第一方资产**归入 `Assets/_Game/`,下划线前缀使其在字母排序中始终置顶。
|
||
|
||
```
|
||
Assets/
|
||
├── _Game/ ← 所有第一方资产(Art、Data、Prefabs、Scenes、Scripts 等)
|
||
│
|
||
├── AddressableAssetsData/ ← Unity 托管,必须保持在 Assets/ 根
|
||
├── Feel/ ← 第三方(只读)
|
||
├── Opsive/ ← 第三方(只读)
|
||
├── PathBerserker2d/ ← 第三方(只读)
|
||
├── Plugins/ ← 第三方(只读)
|
||
└── Tests/ ← 测试(可独立于 _Game/)
|
||
```
|
||
|
||
### 迁移注意事项
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| `AddressableAssetsData/` | **必须留在 `Assets/` 根目录**,Unity Addressables 硬编码此路径 |
|
||
| `Settings/` | URP asset、Input Actions 等 Unity 项目设置文件可随 `_Game/` 迁移 |
|
||
| `Resources/` | 如存在,应逐步清空并删除;过渡期可临时留在根目录 |
|
||
| `StreamingAssets/` | 必须留在 `Assets/` 根目录(Unity 特殊文件夹) |
|
||
| asmdef 路径 | 迁移 `Scripts/` 后需在 Unity 中重新扫描,asmdef 引用由 GUID 追踪,路径变更不影响依赖 |
|
||
|
||
---
|
||
|
||
## 1. 整体目录结构总览
|
||
|
||
```
|
||
Assets/
|
||
├── _Game/ ← 所有第一方游戏资产
|
||
│ ├── Art/ 美术源文件(Sprites、Animations、Materials、Atlases)
|
||
│ │ ├── Characters/ 角色美术(玩家 / 敌人 / NPC)
|
||
│ │ │ ├── Player/ 按形态 ID 分子目录(Player01、Player02…)
|
||
│ │ │ ├── Enemies/ 按敌人 ID 分子目录(E001、E002…)
|
||
│ │ │ └── NPCs/ 非战斗 NPC,按角色名分子目录
|
||
│ │ ├── Environment/ 场景环境(Tilesets、Backgrounds、Props)
|
||
│ │ ├── Effects/ 特效美术(Sprites、Materials、Atlases)
|
||
│ │ ├── UI/ UI 专用图片(Icons、Frames、Backgrounds、Atlases、Materials)
|
||
│ │ │ ├── Icons/
|
||
│ │ │ │ ├── Skills/ 技能图标
|
||
│ │ │ │ ├── Items/ 道具 / 护身符图标
|
||
│ │ │ │ ├── Status/ 状态效果图标
|
||
│ │ │ │ └── InputKeys/ 按键/手柄按键图标(供 InputDeviceIconSetSO 引用)
|
||
│ │ │ ├── Frames/
|
||
│ │ │ ├── Backgrounds/
|
||
│ │ │ └── Atlases/
|
||
│ │ └── Shared/ 跨模块复用基础资产(Palettes、Textures、Materials)
|
||
│ │
|
||
│ ├── Data/ ScriptableObject 资产(按模块分类)
|
||
│ │ ├── Events/ 事件频道 SO(按模块分子目录)
|
||
│ │ ├── Player/
|
||
│ │ ├── Combat/
|
||
│ │ ├── Enemies/
|
||
│ │ ├── Progression/
|
||
│ │ ├── Audio/
|
||
│ │ ├── World/
|
||
│ │ ├── UI/
|
||
│ │ │ ├── Panels/ UI 面板配置 SO
|
||
│ │ │ └── InputIcons/ 按键图标集 SO(InputDeviceIconSetSO,每设备一个文件)
|
||
│ │ └── Settings/
|
||
│ │
|
||
│ ├── Prefabs/ 预制体
|
||
│ │ ├── Player/
|
||
│ │ ├── Enemies/
|
||
│ │ ├── Combat/
|
||
│ │ ├── Effects/
|
||
│ │ ├── Environment/ 场景骨架结构(Tilemap 层、视差背景层)
|
||
│ │ ├── World/
|
||
│ │ ├── UI/
|
||
│ │ └── Persistent/ Persistent 场景专属 Prefabs
|
||
│ │
|
||
│ ├── Scenes/ 场景文件
|
||
│ │ └── Testings/ 测试专用场景(不进入 Addressables 构建)
|
||
│ │
|
||
│ ├── Scripts/ 游戏代码(见 Architecture/01_ProjectStructure.md)
|
||
│ │
|
||
│ ├── Shaders/ 自定义着色器 & HLSL include
|
||
│ │ ├── BaseASE/ Shader Graph / ASE 材质图
|
||
│ │ └── Includes/ 共享 HLSL 函数库(ColorUtils、NoiseUtils 等)
|
||
│ │
|
||
│ ├── UI Toolkit/ UITK 资产(UXML、USS、主题)
|
||
│ │ ├── Layouts/
|
||
│ │ ├── Styles/
|
||
│ │ └── UnityThemes/
|
||
│ │
|
||
│ └── Settings/ URP 配置、Input Actions 等项目设置资产
|
||
│
|
||
├── AddressableAssetsData/ ← Unity 托管,必须在 Assets/ 根(不可移动)
|
||
├── StreamingAssets/ ← Unity 特殊文件夹(如有 FMOD bank)
|
||
├── Feel/ ← MoreMountains Feel 插件(只读)
|
||
├── Opsive/ ← Behavior Designer 插件(只读)
|
||
├── PathBerserker2d/ ← 寻路插件(只读)
|
||
├── Plugins/ ← 其他第三方插件(只读)
|
||
└── Tests/ ← EditMode / PlayMode 测试(可在 _Game/ 外独立维护)
|
||
```
|
||
|
||
> **强制约束**:`AddressableAssetsData/` 和 `StreamingAssets/` 是 Unity 硬编码路径,**永远不得移入 `_Game/`**。所有第三方插件目录**不修改内部结构**,定制内容一律放入 `_Game/` 下的对应模块目录。
|
||
|
||
---
|
||
|
||
## 2. Art/ 美术资源规范
|
||
|
||
### 2.1 目录结构
|
||
|
||
```
|
||
Art/
|
||
├── Characters/ 角色美术资产(玩家 / 敌人 / NPC)
|
||
│ ├── Player/ 玩家角色,按形态 ID 分子目录
|
||
│ │ └── {FormID}/ 例:Player01、Player02
|
||
│ │ ├── Sprites/ 像素帧图 (.png) + Emission 自发光贴图,PPU=32, Filter=Point · PLY_{FormID}_{Action}.png
|
||
│ │ ├── Animations/ 动作片段 (.anim) + 状态机控制器 (.controller),12fps · {Action}.anim / PLY_{FormID}_Animator.controller
|
||
│ │ ├── Materials/ 渲染材质 (.mat),引用角色 Shader(控制 Emission、受击闪白参数)· PLY_{FormID}.mat
|
||
│ │ └── Atlases/ Sprite 图集 (.spriteatlas),合并同形态所有帧,减少 DrawCall · Atlas_Player_{FormID}.spriteatlas
|
||
│ ├── Enemies/ 敌人,按 ID 分子目录(ID 与 AddressKeys ENM_ 前缀对应)
|
||
│ │ └── {EnemyID}/ 例:E001、E002
|
||
│ │ ├── Sprites/ 像素帧图 (.png) + Emission 贴图,PPU=32 · {ID}_{Name}_{Action}.png
|
||
│ │ ├── Animations/ 动作片段 (.anim) + 状态机控制器 (.controller) · {Action}.anim / {ID}_{Name}_Animator.controller
|
||
│ │ ├── Materials/ 渲染材质 (.mat),引用角色 Shader · {ID}.mat
|
||
│ │ └── Atlases/ Sprite 图集 (.spriteatlas),含主体与 Emission 帧 · Atlas_Enemy_{ID}.spriteatlas
|
||
│ └── NPCs/ 非战斗 NPC,按角色名分子目录
|
||
│ └── {NPCName}/
|
||
│ ├── Sprites/ 像素帧图 (.png) · {NPCName}_{Action}.png
|
||
│ ├── Animations/ 动作片段 (.anim) + 状态机控制器 (.controller) · {Action}.anim / {NPCName}_Animator.controller
|
||
│ ├── Materials/ 渲染材质 (.mat) · NPC_{NPCName}.mat
|
||
│ └── Atlases/ Sprite 图集 (.spriteatlas) · Atlas_NPC_{NPCName}.spriteatlas
|
||
├── Environment/ 场景环境资产
|
||
│ ├── Tilesets/ 瓦片纹理 (.png),配合 RuleTile 实现地形自动拼接
|
||
│ │ └── {Region}/ 按区域分子目录(例:Forest、Dungeon、Cave)· TILE_{Region}_{Name}.png
|
||
│ ├── Backgrounds/ 视差滚动背景图 (.png),按 Far / Mid / Near 分层渲染
|
||
│ │ └── {Region}/ 按区域分子目录 · BG_{Region}_{Layer}.png
|
||
│ └── Props/ 可复用场景道具纹理(箱子、灯柱、机关等,无逻辑纯视觉)
|
||
│ └── {Category}/ 按类别分子目录(例:Furniture、Traps、Lights)· PROP_{Category}_{Name}.png
|
||
├── Effects/ 特效美术资产(Prefab 见 Prefabs/Effects/,此处仅存源图与材质)
|
||
│ ├── Sprites/ VFX 帧序列图 (.png),PPU=32,用于粒子 / 帧动画特效 · VFX_{Description}.png
|
||
│ ├── Materials/ 特效专用材质 (.mat),引用 Effects Shader(支持扭曲、混合)· VFX_{Description}.mat
|
||
│ └── Atlases/ 高频特效 Sprite 图集 (.spriteatlas),减少特效渲染批次 · Atlas_Effects_{Name}.spriteatlas
|
||
├── UI/ UI 专用图片(布局 / 样式见 UI Toolkit/ 目录)
|
||
│ ├── Icons/ 图标按子类分目录,统一 32x32 或 64x64 规格
|
||
│ │ ├── Skills/ 技能图标,用于技能栏 / 技能选择界面 · IC_Skills_{Name}.png
|
||
│ │ ├── Items/ 道具 / 护身符图标,用于物品栏 · IC_Items_{Name}.png
|
||
│ │ ├── Status/ 状态效果图标(中毒、燃烧等),用于角色状态栏 · IC_Status_{Name}.png
|
||
│ │ └── InputKeys/ 按键/手柄按键图标,用于 InputDeviceIconSetSO 绑定路径图标映射 · IC_Key_{DeviceShort}_{KeyName}.png
|
||
│ ├── Frames/ 面板框架、血条框、对话框边框等 (.png) · FRAME_{Description}.png
|
||
│ ├── Backgrounds/ 界面背景图、全屏半透明遮罩、渐变填充图 (.png) · UIBG_{Description}.png
|
||
│ └── Atlases/ UI 图标与框架图集 (.spriteatlas),减少 UI 渲染批次 · Atlas_UI_{Category}.spriteatlas
|
||
└── Shared/ 跨模块复用的基础资产,不属于任何具体角色或场景
|
||
├── Palettes/ 色板参考文件 (.png / .aco),仅供美术设计参考,不用于运行时
|
||
└── Textures/ 通用基础纹理:噪点图、渐变纹理、光晕贴图,供 Shader 采样使用
|
||
```
|
||
|
||
### 2.2 美术文件命名规则
|
||
|
||
| 资产类型 | 存放位置 | 命名格式 | 示例 |
|
||
|---------|---------|---------|------|
|
||
| 敌人 Sprite Sheet | `_Game/Art/Characters/Enemies/{EnemyID}/Sprites/` | `{ID}_{Name}_{Action}.png` | `E001_CaoZhi_Idle.png` |
|
||
| 敌人 Emission 贴图 | `_Game/Art/Characters/Enemies/{EnemyID}/Sprites/` | `{ID}_{Name}_{Action}_Emission.png` | `E001_CaoZhi_Idle_Emission.png` |
|
||
| 敌人 AnimationClip | `_Game/Art/Characters/Enemies/{EnemyID}/Animations/` | `{Action}.anim` | `Idle.anim`、`Skill_Start.anim` |
|
||
| 敌人 AnimatorController | `_Game/Art/Characters/Enemies/{EnemyID}/Animations/` | `{ID}_{Name}_Animator.controller` | `E001_CaoZhi_Animator.controller` |
|
||
| 敌人材质 | `_Game/Art/Characters/Enemies/{EnemyID}/Materials/` | `{ID}.mat` | `E001.mat` |
|
||
| 玩家 Sprite Sheet | `_Game/Art/Characters/Player/{FormID}/Sprites/` | `PLY_{FormID}_{Action}.png` | `PLY_Player01_Run.png` |
|
||
| 玩家 AnimationClip | `_Game/Art/Characters/Player/{FormID}/Animations/` | `{Action}.anim` | `Idle.anim`、`Attack01.anim` |
|
||
| 玩家材质 | `_Game/Art/Characters/Player/{FormID}/Materials/` | `PLY_{FormID}.mat` | `PLY_Player01.mat` |
|
||
| 特效 Sprite Sheet | `_Game/Art/Effects/Sprites/` | `VFX_{Description}.png` | `VFX_HitSpark_Sheet.png` |
|
||
| 特效材质 | `_Game/Art/Effects/Materials/` | `VFX_{Description}.mat` | `VFX_HitSpark.mat` |
|
||
| 瓦片纹理 | `_Game/Art/Environment/Tilesets/{Region}/` | `TILE_{Region}_{Name}.png` | `TILE_Forest_Ground.png` |
|
||
| 背景层 | `_Game/Art/Environment/Backgrounds/{Region}/` | `BG_{Region}_{Layer}.png` | `BG_Forest_Far.png` |
|
||
| 场景道具 | `_Game/Art/Environment/Props/{Category}/` | `PROP_{Category}_{Name}.png` | `PROP_Furniture_Chest.png` |
|
||
| UI 图标 | `_Game/Art/UI/Icons/{SubType}/` | `IC_{Category}_{Name}.png` | `IC_Skills_SoulBlade.png` |
|
||
| 按键图标 | `_Game/Art/UI/Icons/InputKeys/` | `IC_Key_{DeviceShort}_{KeyName}.png` | `IC_Key_KBM_Space.png`、`IC_Key_Xbox_A.png` |
|
||
| UI 框架 | `_Game/Art/UI/Frames/` | `FRAME_{Description}.png` | `FRAME_HealthBar.png` |
|
||
| UI 背景 | `_Game/Art/UI/Backgrounds/` | `UIBG_{Description}.png` | `UIBG_PauseMenu.png` |
|
||
| 色板参考 | `_Game/Art/Shared/Palettes/` | `PAL_{Name}.png` | `PAL_Forest.png` |
|
||
|
||
### 2.3 Sprite Atlas 策略
|
||
|
||
| Atlas 文件 | 覆盖内容 | 存放位置 |
|
||
|-----------|---------|--------|
|
||
| `Atlas_Player_{FormID}.spriteatlas` | 该形态玩家所有 Sprite | `_Game/Art/Characters/Player/{FormID}/Atlases/` |
|
||
| `Atlas_Enemy_{EnemyID}.spriteatlas` | 该敌人所有 Sprite(含 Emission)| `_Game/Art/Characters/Enemies/{EnemyID}/Atlases/` |
|
||
| `Atlas_NPC_{NPCName}.spriteatlas` | 该 NPC 所有 Sprite | `_Game/Art/Characters/NPCs/{NPCName}/Atlases/` |
|
||
| `Atlas_Effects_Common.spriteatlas` | 通用高频特效 Sprite | `_Game/Art/Effects/Atlases/` |
|
||
| `Atlas_UI_Icons.spriteatlas` | 所有 UI 图标(技能/道具/状态)| `_Game/Art/UI/Atlases/` |
|
||
| `Atlas_UI_Frames.spriteatlas` | 面板框架、血条框等 | `_Game/Art/UI/Atlases/` |
|
||
|
||
**规则**:
|
||
- Atlas 文件放在**被打包 Sprite 的同目录下的 `Atlases/` 子文件夹**,而非集中到单独目录
|
||
- **Atlas 本身不注册 Addressable**,通过所属 Prefab/Material 间接引用,由 Unity 自动处理依赖
|
||
- 区域特有的敌人或环境资产可单独建 Atlas,避免跨区域 Atlas 导致整体加载
|
||
- Atlas 内不混入不同生命周期的资产(例如:角色 Sprite 与 UI 图标不合并)
|
||
|
||
---
|
||
|
||
## 3. Data/ ScriptableObject 规范
|
||
|
||
### 3.1 完整目录结构
|
||
|
||
```
|
||
Data/
|
||
├── Events/ 所有事件频道 SO(每个事件独立一个文件)
|
||
│ ├── Core/ 游戏状态、场景加载等核心事件
|
||
│ ├── Player/ 玩家相关事件
|
||
│ ├── Combat/ 战斗相关事件
|
||
│ ├── Enemies/ 敌人相关事件
|
||
│ ├── World/ 世界交互事件(含 EVT_ShowInteractPrompt、EVT_HideInteractPrompt)
|
||
│ ├── UI/ UI 显隐事件(含 EVT_InputDeviceChanged)
|
||
│ ├── Audio/ 音频播放事件
|
||
│ ├── Progression/ 进度成长事件
|
||
│ ├── Dialogue/ 对话事件
|
||
│ ├── Quest/ 任务事件
|
||
│ ├── Boss/ Boss 相关事件
|
||
│ └── Difficulty/ 难度调整事件
|
||
├── Player/
|
||
│ ├── Forms/ 各形态配置
|
||
│ └── Input/ 输入配置
|
||
├── Combat/
|
||
│ ├── DamageSources/ 伤害源配置
|
||
│ └── Weapons/ 武器配置
|
||
├── Enemies/
|
||
│ └── {EnemyID}/ 每个敌人的数据目录
|
||
├── Progression/
|
||
│ ├── Skills/ 技能配置
|
||
│ ├── Spells/ 法术配置
|
||
│ ├── Charms/ 护身符配置
|
||
│ └── Abilities/ 能力配置
|
||
├── Audio/
|
||
│ ├── BGM/ 背景音乐配置
|
||
│ └── SFX/ 音效配置
|
||
├── World/
|
||
│ ├── Map/ 地图与房间配置
|
||
│ └── Shop/ 商店配置
|
||
├── UI/
|
||
│ ├── Panels/ UI 面板配置
|
||
│ └── InputIcons/ 按键图标集 SO(每设备一个文件,通过 Inspector 直接引用,不走 Addressables)
|
||
└── Settings/ 全局设置与难度配置
|
||
```
|
||
|
||
### 3.2 SO 资产命名规则
|
||
|
||
格式:`{SystemPrefix}_{描述}.asset`,参考 `Architecture/01_ProjectStructure.md §3` 前缀表。
|
||
|
||
| 前缀 | 系统 | 示例 |
|
||
|------|------|------|
|
||
| `EVT_` | 事件频道 | `EVT_PlayerDied.asset` |
|
||
| `PLY_` | 玩家 | `PLY_PlayerStats.asset` |
|
||
| `CMB_` | 战斗 | `CMB_DamageSource_Sword.asset` |
|
||
| `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` |
|
||
| `AUD_` | 音频 | `AUD_BGMPlaylist_Forest.asset` |
|
||
| `UI_` | UI 配置 | `UI_PanelConfig_HUD.asset` |
|
||
| `SET_` | 设置 | `SET_GlobalSettings.asset` |
|
||
| `ABL_` | 能力 | `ABL_DoubleJump.asset` |
|
||
| `ICN_` | 按键图标集 | `ICN_KeyboardMouse.asset`、`ICN_Xbox.asset` |
|
||
|
||
### 3.3 事件频道 SO 特别规则
|
||
|
||
- 每个事件频道**独立一个文件**,禁止在同一 `.cs` 脚本中定义多个频道类(防止 Script 引用丢失)
|
||
- 文件名与类型名严格对应:`EVT_PlayerDied.asset` 对应 `PlayerDiedEventChannelSO`
|
||
- **事件频道 SO 不注册 Addressable**,通过 Inspector 直接引用
|
||
|
||
---
|
||
|
||
## 4. Prefabs/ 预制体规范
|
||
|
||
### 4.1 目录结构
|
||
|
||
```
|
||
Prefabs/
|
||
├── Player/ 玩家顶级 Prefab,含控制器 / 动画 / 碰撞体(Addressable:PLY_Player)· PLY_Player.prefab
|
||
├── Enemies/
|
||
│ └── {EnemyID}/ 敌人顶级 Prefab,含 AI 行为树 / 动画 / 碰撞体(Addressable:ENM_{Name})· ENM_{Name}.prefab
|
||
├── Combat/
|
||
│ ├── HitBox/ 主动攻击碰撞盒,嵌套于角色 Prefab 内,随角色一同打包,不单独注册 Addressable
|
||
│ ├── HurtBox/ 受击判定盒,同上规则,不单独注册 Addressable
|
||
│ └── Projectiles/ 抛射物顶级 Prefab,独立实例化,纳入对象池(标签 Poolable)· PROJ_{Name}.prefab
|
||
├── Effects/ 特效顶级 Prefab(粒子系统 / 帧动画),纳入对象池,标签 Poolable · VFX_{Name}.prefab
|
||
├── Collectibles/ 可收集物件(灵魂碎片、道具、恢复球),纳入对象池,标签 Poolable · COL_{Name}.prefab├── Environment/ 场景骨架结构 Prefab,由关卡场景直接引用,不注册 Addressable
|
||
│ ├── Tilemaps/ Tilemap 层 GameObject Prefab,含 Grid / TilemapRenderer / Collider2D,每种地形层独立一个 Prefab · ENV_Tilemap_{Layer}.prefab
|
||
│ └── Backgrounds/ 视差滚动背景层 Prefab,含 SpriteRenderer + ParallaxScroller,每区域按 Far / Mid / Near 分层 · ENV_BG_{Region}_{Layer}.prefab├── World/
|
||
│ ├── Interactables/ 场景可交互物件(宝箱、NPC 对话触发器、传送门),含交互逻辑组件 · WLD_{Name}.prefab
|
||
│ ├── Traps/ 机关陷阱(刺、摆锤、喷火),含周期性伤害触发逻辑 · WLD_{Name}.prefab
|
||
│ └── Props/ 纯视觉场景道具(无逻辑),用于场景布景装饰 · WLD_{Name}.prefab
|
||
├── UI/ UI 面板顶级 Prefab,由 UIManager 通过 Addressable 实例化(组:UI)· UI_{PanelName}.prefab
|
||
└── Persistent/ 持久场景全局管理器,随 Persistent 场景加载,全程不销毁 · SYS_{ManagerName}.prefab
|
||
```
|
||
|
||
### 4.2 Prefab 命名规则
|
||
|
||
| 类型 | 前缀 | 示例 |
|
||
|------|------|------|
|
||
| 玩家 | `PLY_` | `PLY_Player.prefab` |
|
||
| 敌人 | `ENM_` | `ENM_GruntWarrior.prefab` |
|
||
| 抛射物 | `PROJ_` | `PROJ_Arrow.prefab` |
|
||
| 特效 | `VFX_` | `VFX_HitSpark.prefab` |
|
||
| UI | `UI_` | `UI_HUD.prefab` |
|
||
| 收集物 | `COL_` | `COL_HPOrb.prefab` |
|
||
| 世界物件 | `WLD_` | `WLD_Torch.prefab` |
|
||
| 武器 | `WPN_` | `WPN_SkyBlade.prefab` |
|
||
| 持久对象 | `SYS_` | `SYS_GameManager.prefab` |
|
||
| 环境结构 | `ENV_` | `ENV_Tilemap_Ground.prefab`、`ENV_BG_Forest_Far.prefab` |
|
||
|
||
### 4.3 Prefab 嵌套规则
|
||
|
||
- Prefab 内的子物件(HitBox、HurtBox、骨骼节点)**不单独注册 Addressable**
|
||
- 武器 Prefab 嵌套在角色 Prefab 内时,通过 Nested Prefab 引用,不用 Addressables 动态加载
|
||
- 只有**顶级可实例化对象**才注册 Addressable 地址
|
||
|
||
---
|
||
|
||
## 5. Scenes/ 场景规范
|
||
|
||
### 5.1 目录结构
|
||
|
||
```
|
||
Scenes/
|
||
├── Persistent.unity 常驻场景,承载全局管理器 Prefab(GameManager / AudioManager / UIManager),永不卸载
|
||
├── MainMenu.unity 主菜单场景,游戏启动后首先加载,含主题音乐与过场动画
|
||
├── Room_{Region}_{Index:D2}.unity 普通关卡房间,含静态地形与区域触发器(敌人 / 道具由 Spawner 动态实例化)· 例:Room_Forest_01.unity
|
||
├── Boss_{Name}.unity Boss 专属战斗场景,含专属 BGM、Boss AI 与阶段触发逻辑 · 例:Boss_CaoZhi.unity
|
||
└── Testings/ 开发测试专用场景,不注册 Addressable,不进入正式构建流程
|
||
```
|
||
|
||
### 5.2 场景命名规则
|
||
|
||
| 类型 | 命名格式 | Addressable 地址 |
|
||
|------|---------|----------------|
|
||
| 常驻场景 | `Persistent.unity` | `Scene_Persistent` |
|
||
| 主菜单 | `MainMenu.unity` | `Scene_MainMenu` |
|
||
| 关卡房间 | `Room_{Region}_{Index:D2}.unity` | `Room_Forest_01` |
|
||
| Boss 战 | `Boss_{Name}.unity` | `Boss_CaoZhi` |
|
||
| 测试场景 | 任意(在 Testings/) | **不注册 Addressable** |
|
||
|
||
### 5.3 场景内容规范
|
||
|
||
- **Persistent 场景**:只放全局管理器 Prefab(`SYS_GameManager`、`SYS_AudioManager`、`SYS_UIManager`),其余全部通过 Addressables 动态加载
|
||
- **关卡场景**:只放该关卡的静态地形与触发器;角色、敌人由 Spawner 通过 Addressables 实例化
|
||
- 禁止在场景中直接拖拽引用 `Prefabs/` 下的动态对象(改用 Spawner + Addressable Key)
|
||
|
||
---
|
||
|
||
## 6. Shaders/ 着色器规范
|
||
|
||
### 6.1 目录结构
|
||
|
||
```
|
||
_Game/Shaders/
|
||
├── BaseASE/ Shader Graph 图,每个文件对应一个渲染目的,不合并不相关效果 · {Category}_{Purpose}.shadergraph
|
||
│ ├── Character/ 角色类:主材质(Emission 自发光 + 受击闪白参数)、描边、溶解 / 死亡效果
|
||
│ ├── Environment/ 环境类:Tilemap 地形着色、多层视差背景、水面 / 液体流动效果
|
||
│ ├── Effects/ 特效类:VFX Sprite 通用(Alpha 混合 + 颜色偏移)、热浪扭曲
|
||
│ └── UI/ UI 类:默认 UI 渲染、灰度效果(用于禁用状态的技能 / 道具图标)
|
||
└── Includes/ 跨 Shader 共享 HLSL 函数库,通过相对路径 #include 引用 · {FunctionGroup}.hlsl
|
||
```
|
||
|
||
### 6.2 Shader 命名规则
|
||
|
||
| 类型 | 命名格式 | 示例 |
|
||
|------|---------|------|
|
||
| Shader Graph | `{Category}_{Purpose}.shadergraph` | `Character_Main.shadergraph` |
|
||
| HLSL include | `{FunctionGroup}.hlsl` | `ColorUtils.hlsl` |
|
||
| Shader Variant Collection | `SVC_{Category}.shadervariants` | `SVC_Characters.shadervariants` |
|
||
|
||
### 6.3 Shader 管理规则
|
||
|
||
- Shader 资产**不注册 Addressable**,由 Material 直接引用,Material 随 Prefab 打包
|
||
- HLSL include 文件放在 `Shaders/Includes/`,使用**相对路径** `#include` 引用
|
||
- 每个渲染目的对应一个 `.shadergraph`,**不合并多个不相关效果到同一 Graph**
|
||
- Shader 变体数量需受控:通过 `Shader Variant Collection` 预热,避免运行时卡顿
|
||
|
||
---
|
||
|
||
## 6.5 Material 管理规范
|
||
|
||
### 6.5.1 Material 存放原则
|
||
|
||
Material(`.mat`)**紧邻使用它的资产存放**,不设全局集中目录:
|
||
|
||
| 使用对象 | Material 存放位置 | 命名格式 | 示例 |
|
||
|---------|----------------|---------|------|
|
||
| 玩家角色 | `_Game/Art/Characters/Player/{FormID}/Materials/` | `PLY_{FormID}.mat` | `PLY_Player01.mat` |
|
||
| 敌人 | `_Game/Art/Characters/Enemies/{EnemyID}/Materials/` | `ENM_{ID}.mat` | `ENM_E001.mat` |
|
||
| NPC | `_Game/Art/Characters/NPCs/{NPCName}/Materials/` | `NPC_{Name}.mat` | `NPC_Merchant.mat` |
|
||
| 特效 VFX | `_Game/Art/Effects/Materials/` | `VFX_{Description}.mat` | `VFX_HitSpark.mat` |
|
||
| 环境/Tilemap | `_Game/Art/Environment/Tilesets/{Region}/Materials/` | `TILE_{Region}_{Name}.mat` | `TILE_Forest_Ground.mat` |
|
||
| 环境背景 | `_Game/Art/Environment/Backgrounds/{Region}/Materials/` | `BG_{Region}.mat` | `BG_Forest.mat` |
|
||
| 场景道具 | `_Game/Art/Environment/Props/{Category}/Materials/` | `PROP_{Name}.mat` | `PROP_Chest.mat` |
|
||
| UI 专用 | `_Game/Art/UI/Materials/` | `UI_{Description}.mat` | `UI_HealthBar.mat` |
|
||
| 共享/通用 | `_Game/Art/Shared/Materials/` | `MAT_{Description}.mat` | `MAT_Dissolve.mat` |
|
||
|
||
### 6.5.2 Material 命名规则
|
||
|
||
- 同一对象有多个 Material 时加 `_{Variant}` 后缀区分:
|
||
- `ENM_E001.mat`(主材质)
|
||
- `ENM_E001_Emission.mat`(发光变体,若需要单独材质)
|
||
- `ENM_E001_Flash.mat`(受击闪白材质,通过代码切换)
|
||
- Emission 贴图与主贴图共享同一 Material,通过 Shader 属性 `_EmissionMap` 关联,**无需单独 Material**
|
||
- 受击闪白效果推荐通过 Shader 属性(如 `_FlashAmount`)在运行时控制,避免 Material 实例爆炸
|
||
|
||
### 6.5.3 Material 实例化规则
|
||
|
||
```csharp
|
||
// ✅ 推荐:通过 MaterialPropertyBlock 修改,不产生 Material 实例
|
||
var mpb = new MaterialPropertyBlock();
|
||
mpb.SetFloat("_FlashAmount", 1f);
|
||
renderer.SetPropertyBlock(mpb);
|
||
|
||
// ⚠ 避免:直接修改 renderer.material(每次调用都创建新实例,造成内存泄漏)
|
||
renderer.material.SetFloat("_FlashAmount", 1f); // ⚠ 产生实例
|
||
|
||
// ✅ 允许:需要持久独立状态时显式用 Instantiate,并在 OnDestroy 中手动 Destroy
|
||
_matInstance = Instantiate(renderer.sharedMaterial);
|
||
renderer.material = _matInstance;
|
||
// ... OnDestroy: Destroy(_matInstance);
|
||
```
|
||
|
||
---
|
||
|
||
## 7. UI Toolkit/ 规范
|
||
|
||
```
|
||
UI Toolkit/
|
||
├── PanelSettings.asset 面板渲染配置(Scale Mode、Sort Order、Reference Resolution),全局唯一,不得创建多个
|
||
├── UnityThemes/ Unity 编辑器内置主题文件,不修改
|
||
├── Layouts/ UXML 布局文件,每个面板对应一个文件,与 Prefabs/UI/ 同名 · {PanelName}.uxml
|
||
└── Styles/ USS 样式表:Variables.uss(全局 CSS 变量)、Common.uss(通用控件样式)、{PanelName}.uss(面板专属样式)
|
||
```
|
||
|
||
- `PanelSettings.asset` 全局唯一,不得创建多个
|
||
- UXML 和 USS 按界面功能命名,与对应的 `Prefabs/UI/` 同名
|
||
|
||
---
|
||
|
||
## 8. Addressables 管理规范
|
||
|
||
### 8.1 分组(Group)划分策略
|
||
|
||
| 组名 | 包含内容 | Build 类型 | 加载时机 |
|
||
|------|---------|-----------|---------|
|
||
| `Default Local Group` | 常驻 Prefab(GameManager、UIManager 等)、全局配置 SO | Local | 启动时自动加载 |
|
||
| `UI` | 所有 UI Prefab(HUD、菜单、弹框等) | Local | 启动时预加载 |
|
||
| `Player` | 玩家 Prefab、武器 Prefab | Local | 游戏开始时加载 |
|
||
| `VFX_Common` | 通用高频特效(HitSpark、BloodSplat 等) | Local | 启动时预加载 |
|
||
| `Collectibles` | 收集物 Prefab(Geo、Item、HPOrb) | Local | 启动时预加载 |
|
||
| `Projectiles` | 抛射物 Prefab | Local | 启动时预加载 |
|
||
| `Enemies` | 所有敌人 Prefab(`ENM_*`) | Local | 进入区域时加载 |
|
||
| `Room_{Region}` | 该区域的关卡场景 + 区域专属资产 | Local | 进入区域时加载 |
|
||
| `Boss_{Name}` | Boss 专属 Prefab + 场景 | Local | Boss 战开始前加载 |
|
||
| `Audio_Music` | BGM 音频(FMOD bank 引用) | Remote(可选)| 按需流式加载 |
|
||
| `Config` | 运行时需要动态加载的配置 SO | Local | 按需加载 |
|
||
|
||
**划分原则**:
|
||
1. **生命周期相同的资源放同一组**——一起加载、一起卸载
|
||
2. **不同区域的资源绝对隔离**——防止 Region A 的资产随 Region B 打包
|
||
3. **高频小资产合入 Common 组**——避免大量小 handle 的运行时开销
|
||
4. **场景文件与其依赖资产放同一组**——确保 SceneManager 加载时依赖已在本地
|
||
|
||
### 8.2 Address 命名规则
|
||
|
||
地址字符串格式:`{SystemPrefix}_{描述}` 或 `{Category}/{描述}`
|
||
|
||
```
|
||
# Prefab 类(无路径前缀)
|
||
PLY_Player
|
||
ENM_GruntWarrior
|
||
ENM_SkullArcher
|
||
PROJ_Arrow
|
||
VFX_HitSpark
|
||
UI_HUD
|
||
COL_HPOrb
|
||
|
||
# 场景类
|
||
Scene_Persistent
|
||
Scene_MainMenu
|
||
Room_Forest_01
|
||
Boss_CaoZhi
|
||
|
||
# 配置数据类(带路径前缀区分)
|
||
Config/FootstepCatalog
|
||
Config/DifficultyEasy
|
||
```
|
||
|
||
**强制要求**:所有 Address 必须在 `AddressKeys.cs` 中定义对应常量,**禁止在代码中硬编码字符串**。
|
||
|
||
### 8.3 Label(标签)使用规范
|
||
|
||
> 完整定义见 `Standards/AddressablesLabelSpec.md`。
|
||
|
||
| 标签 | 用途 | 相关常量 |
|
||
|------|------|---------|
|
||
| `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` 和 `Preload` 标签)
|
||
- 新增标签前确认是否有批量加载的实际需求,避免标签膨胀(决策流程见 `AddressablesLabelSpec.md §6`)
|
||
|
||
### 8.4 AddressKeys.cs 维护流程
|
||
|
||
文件路径:`Assets/_Game/Scripts/Core/Assets/AddressKeys.cs`
|
||
|
||
**工作流(添加新资产)**:
|
||
|
||
```
|
||
1. 在 Project 中创建/导入资产
|
||
2. 在 AddressKeys.cs 中添加对应 const 字符串
|
||
3. 在 AddressableBatchTool(菜单 `BaseGames/Addressables/Addressable Batch Tool`)中:
|
||
a. 切换到 "① 同步 AddressKeys" 标签
|
||
b. 点击 "Scan" 找到未注册的 Key
|
||
c. 选择目标 Group,点击 "Register" 完成注册
|
||
4. 运行 AddressKeyValidator(菜单 `BaseGames/Addressables/Validate Address Keys`)
|
||
确认无 Missing / Mismatch 警告
|
||
5. 提交 AddressKeys.cs 和 AddressableAssetSettings.asset 的修改
|
||
```
|
||
|
||
**工作流(删除/重命名资产)**:
|
||
|
||
```
|
||
1. 先在 AddressKeys.cs 中删除/修改对应常量
|
||
2. 全局搜索该常量的所有引用并更新
|
||
3. 在 Addressables Groups 窗口手动删除或重命名对应条目
|
||
4. 重新运行 AddressKeyValidator 验证
|
||
5. 提交所有修改(.cs + .asset 文件)
|
||
```
|
||
|
||
### 8.5 AssetLoader 使用规范
|
||
|
||
封装类路径:`Assets/_Game/Scripts/Core/Assets/AssetLoader.cs`
|
||
|
||
```csharp
|
||
// ✅ 正确:使用 AssetLoader + AddressKeys 常量
|
||
var (prefab, handle) = await AssetLoader.LoadAsync<GameObject>(AddressKeys.PrefabPlayer);
|
||
_tracker.Track(handle); // 注册到 AssetReleaseTracker,场景卸载时自动 Release
|
||
|
||
// ✅ 正确:对象池中不直接 Release,由池管理器统一处理
|
||
|
||
// ❌ 禁止:直接调用 Addressables API(绕过封装层)
|
||
var handle = Addressables.LoadAssetAsync<GameObject>("PLY_Player"); // ❌
|
||
|
||
// ❌ 禁止:加载后不 Release(内存泄漏)
|
||
var (prefab, _) = await AssetLoader.LoadAsync<GameObject>(AddressKeys.PrefabPlayer); // ❌ 忘记 Track
|
||
```
|
||
|
||
### 8.6 加载/释放生命周期
|
||
|
||
```
|
||
场景加载时:
|
||
SceneManager 激活 → 场景根 GO 上挂 AssetReleaseTracker
|
||
→ 各 Spawner/Manager 调用 AssetLoader.LoadAsync → Track handle
|
||
|
||
场景卸载时:
|
||
AsyncOperation.completed → AssetReleaseTracker.OnDestroy 自动 Release 所有 handle
|
||
→ 内存归零(无需手动清理)
|
||
|
||
对象池:
|
||
Pool 持有 handle(不 Track 到 AssetReleaseTracker)
|
||
→ Pool 销毁时显式 Release(Pool 自身管理生命周期)
|
||
```
|
||
|
||
### 8.7 Build 策略
|
||
|
||
| 构建目标 | 命令 | 说明 |
|
||
|---------|------|------|
|
||
| 开发测试 | `Build > New Build > Default Build Script` | 全量本地构建,输出到 `Library/com.unity.addressables/` |
|
||
| 内容更新 | `Build > Update a Previous Build` | 仅重打修改的 Group,需保留上次 catalog |
|
||
| 生产发布 | CI 流水线触发全量构建 | Remote Group 上传 CDN,Local Group 打入安装包 |
|
||
|
||
**注意**:`AddressableAssetsData/` 目录下的文件由 Unity 自动维护,**不得手动修改 .asset 内容**,只通过 Addressables Groups 窗口操作。
|
||
|
||
---
|
||
|
||
## 9. Import Settings 规范
|
||
|
||
### 9.1 Sprite / Texture Import 规范
|
||
|
||
| 设置项 | 规范值 | 说明 |
|
||
|-------|-------|------|
|
||
| Texture Type | `Sprite (2D and UI)` | 角色/特效/UI 图 |
|
||
| Sprite Mode | `Multiple`(Sprite Sheet)或 `Single` | Sprite Sheet 用 Multiple |
|
||
| Pixels Per Unit | `32` | 与项目像素密度保持统一 |
|
||
| Filter Mode | `Point (no filter)` | Pixel Art 项目固定值 |
|
||
| Compression | `None`(移动平台用 `ASTC 6x6`)| 开发阶段 None,发布时切换 |
|
||
| Generate Mip Maps | `关闭` | 2D 游戏不需要 Mip Maps |
|
||
| Read/Write Enabled | `关闭`(除非代码需要像素读写) | 减少内存占用 |
|
||
| Max Size | 角色 `2048`,UI `1024`,特效 `512` | 按实际尺寸设置上限 |
|
||
|
||
> **Emission 贴图**(`_Emission.png`)使用 **相同 Import 设置**,与主贴图保持一致的 PPU 和 Filter Mode。
|
||
|
||
### 9.2 AnimationClip Import 规范
|
||
|
||
- 直接创建的 `.anim` 文件(非 FBX 内嵌)无需额外 Import 设置
|
||
- Loop Time:循环动作(Idle、Move、Skill_Loop)开启;非循环(Death、Hit、Skill_Start)关闭
|
||
- Sample Rate:`12` fps(Pixel Art 动画标准帧率)
|
||
|
||
### 9.3 Audio Import 规范
|
||
|
||
| 设置项 | SFX | BGM |
|
||
|-------|-----|-----|
|
||
| Load Type | `Decompress On Load` | `Streaming` |
|
||
| Compression Format | `Vorbis` | `Vorbis` |
|
||
| Quality | `70%` | `60%` |
|
||
| Load In Background | `关闭` | `开启` |
|
||
|
||
> **注**:若使用 FMOD,Audio 资产由 FMOD Studio 管理,Unity 侧只保留 FMOD Bank 引用 SO,不直接导入 AudioClip。
|
||
|
||
---
|
||
|
||
## 10. 资源新增工作流
|
||
|
||
### 10.1 新增敌人
|
||
|
||
> **推荐工具**:`BaseGames → Data → Enemy Data Manager`(`EnemyDataWindow`)——在左栏点击 [New] 可自动创建 `ENM_*_Stats.asset`,在右栏 Loot Tab 配置掉落表。
|
||
|
||
```
|
||
1. _Game/Art/Characters/Enemies/ 下创建 {EnemyID}/ 目录,内含 Sprites/ Animations/ Materials/ Atlases/
|
||
2. 导入 Sprite Sheet 到 Sprites/,配置 Import Settings(PPU=32, Filter=Point, Multiple)
|
||
3. 在 Sprite Editor 中切割 Sprite
|
||
4. 在 Animations/ 下创建动画片段(.anim)和 Animator Controller
|
||
5. 在 Materials/ 下创建材质(引用 _Game/Shaders/ 中的角色 Shader,关联主纹理和 Emission 贴图)
|
||
6. 在 Atlases/ 下创建 Atlas_Enemy_{ID}.spriteatlas,包含该敌人所有 Sprite
|
||
7. 在 Enemy Data Manager(菜单 BaseGames/Data/Enemy Data Manager)创建 ENM_{ID}_Stats.asset
|
||
8. 在 _Game/Prefabs/Enemies/{EnemyID}/ 下创建 ENM_{Name}.prefab
|
||
9. 在 AddressKeys.cs 中添加 PrefabEnemy{Name} 常量
|
||
10. 使用 Rule Sync(菜单 BaseGames/Addressables/Rule Sync)Scan → Fix All,自动分组并打 Enemy 标签
|
||
11. 运行 AddressKeyValidator(菜单 BaseGames/Addressables/Validate Address Keys)验证
|
||
```
|
||
|
||
### 10.2 新增武器(Weapon)
|
||
|
||
> **推荐工具**:`BaseGames → Data → Weapon Editor`(`WeaponEditorWindow`)创建 `WPN_*_Data.asset`;`BaseGames → Create → Weapon HitBox Prefab`(`WeaponHitBoxWizard`)创建 4 方向 HitBox Prefab。
|
||
|
||
```
|
||
1. 在 _Game/Art/Characters/Player/{FormID}/Sprites/ 下放置武器帧动画 Sprite Sheet,配置 Import Settings
|
||
2. 在 Weapon Editor(菜单 BaseGames/Data/Weapon Editor)左栏 [New] 创建 WPN_{Name}_Data.asset
|
||
- 路径:_Game/Data/Combat/Weapons/WPN_{Name}_Data.asset
|
||
- 命名:WPN_{Name}(示例:WPN_SkyBlade、WPN_EarthClaw)
|
||
3. 使用 Weapon HitBox Wizard(菜单 BaseGames/Create/Weapon HitBox Prefab)生成
|
||
_Game/Prefabs/Weapons/WPN_{Name}_HitBox.prefab(自动创建 4 方向 Ground/Up/Down/Air)
|
||
4. 在 _Game/Prefabs/Player/ 下创建或更新武器顶级 Prefab WPN_{Name}.prefab
|
||
5. 在 AddressKeys.cs 中添加 PrefabWeapon{Name} 常量
|
||
6. 使用 Rule Sync 自动分组(Player 组)并打 Weapon + Preload 标签
|
||
7. 运行 AddressKeyValidator 验证
|
||
```
|
||
|
||
### 10.3 新增技能(Skill)
|
||
|
||
> **推荐工具**:`BaseGames → Data → Skill Editor`(`SkillEditorWindow`)创建 `SKL_*_Data.asset`;`BaseGames → Create → Skill HitBox Prefab`(`SkillHitBoxWizard`)创建多段 HitBox Prefab。
|
||
|
||
```
|
||
1. 在 _Game/Art/Characters/Player/{FormID}/Animations/ 下创建技能动画片段(.anim)
|
||
2. 在 Skill Editor(菜单 BaseGames/Data/Skill Editor)左栏 [New] 创建 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(支持多段伤害配置)
|
||
4. 在 AddressKeys.cs 中添加对应常量(如需独立 Addressable 加载)
|
||
5. 运行 AddressKeyValidator 验证(如已注册 Addressable)
|
||
```
|
||
|
||
### 10.4 新增护身符(Charm)
|
||
|
||
> **推荐工具**:`BaseGames → Data → Character Wizard`(切换到 Charm 标签)或直接在 Project 窗口 右键 → Create,使用 `CharmSOEditor`(Custom Inspector)配置,**必须确保路径为 `_Game/Data/Progression/Charms/`,命名为 `CHM_{Name}.asset`**;若护身符类型较多,建议在 §12 中增加专属 Charm Editor 入口以强制规范。
|
||
|
||
```
|
||
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} 常量
|
||
4. 使用 Rule Sync 自动分组(Config 组)并打 Charms 标签
|
||
5. 运行 AddressKeyValidator 验证
|
||
```
|
||
|
||
### 10.5 新增玩家形态(Player Form)
|
||
|
||
> **推荐工具**:`BaseGames → Tools → Character Wizard`(`CharacterWizardWindow`)统一入口——创建 FormSO、绑定武器引用、跳转到 Form Editor;`BaseGames → Data → Form Editor`(`FormEditorWindow`)进行三魂列阵可视化编辑。
|
||
|
||
```
|
||
1. 在 Character Wizard(菜单 BaseGames/Data/Character Wizard)切换到 Player 标签
|
||
- 填写 FormID,点击 [Create Form Assets],自动在正确路径创建 FormSO 和相关 SO
|
||
2. 在 _Game/Art/Characters/Player/{FormID}/ 下创建 Sprites/ Animations/ Materials/ Atlases/ 目录
|
||
3. 导入 Sprite Sheet,配置 Import Settings(PPU=32, Filter=Point, Multiple)
|
||
4. 在 Form Editor(菜单 BaseGames/Data/Form Editor)三栏网格中选择形态格位,绑定武器和技能列表
|
||
5. 在 _Game/Prefabs/Player/ 下创建 PLY_{FormID}.prefab
|
||
6. 在 AddressKeys.cs 中添加 PrefabPlayer{FormID} 常量(如为独立 Addressable)
|
||
7. 使用 Rule Sync 自动分组(Player 组)并打 Preload 标签
|
||
8. 运行 AddressKeyValidator 验证
|
||
```
|
||
|
||
### 10.6 新增 VFX
|
||
|
||
> **提示**:VFX Prefab 必须纳入 `GlobalObjectPool`,在 Pool 配置中指定初始预热数量。
|
||
|
||
```
|
||
1. 在 _Game/Art/Effects/Sprites/ 下导入特效 Sprite Sheet,配置 Import Settings(PPU=32, Filter=Point)
|
||
2. 在 _Game/Art/Effects/Materials/ 下创建特效材质
|
||
3. 在 _Game/Prefabs/Effects/ 下创建 VFX_{Name}.prefab
|
||
4. 在 AddressKeys.cs 中添加 PrefabVFX{Name} 常量
|
||
5. 使用 Rule Sync 自动分组(VFX_Common 组)并打 Poolable + Preload 标签
|
||
6. 在 GlobalObjectPool._warmupConfigs 中添加初始池数量配置
|
||
```
|
||
|
||
### 10.7 新增 UI 界面
|
||
|
||
```
|
||
1. 在 _Game/UI Toolkit/Layouts/ 下创建 {PanelName}.uxml
|
||
2. 在 _Game/UI Toolkit/Styles/ 下创建或复用对应 .uss
|
||
3. 在 _Game/Prefabs/UI/ 下创建 UI_{PanelName}.prefab
|
||
4. 在 _Game/Data/UI/Panels/ 下创建 UI_PanelConfig_{PanelName}.asset(如需配置 SO)
|
||
5. 在 AddressKeys.cs 中添加 PrefabUI{PanelName} 常量
|
||
6. 使用 Rule Sync 自动分组(UI 组);常驻全局面板额外打 Preload 标签
|
||
```
|
||
|
||
### 10.8 新增关卡场景
|
||
|
||
```
|
||
1. 在 _Game/Scenes/ 下创建 Room_{Region}_{Index:D2}.unity
|
||
2. 在 AddressKeys.cs 中添加地址常量(复用 SceneRoomPrefix + 动态拼接或新增独立常量)
|
||
3. 将场景注册到 Room_{Region} 组(Rule Sync 可自动识别 Room_ 前缀并动态计算组名)
|
||
4. 在 _Game/Data/World/Map/ 下创建 MAP_RoomData_{Region}_{Index:D2}.asset
|
||
```
|
||
|
||
### 10.9 新增输入设备图标集(Input Device Icon Set)
|
||
|
||
> **推荐工具**:`BaseGames/Input Icon Studio`(`InputIconStudioWindow`)——可视化管理所有设备的按键图标,自动写入对应 SO。
|
||
|
||
**⚠ Addressable 决策:不需要 Addressable。**
|
||
`InputDeviceIconSetSO` 由 `InputIconService`(挂载在 UIRoot 上)通过 `SerializeField` 直接引用,随常驻场景加载,无需运行时动态加载。
|
||
|
||
```
|
||
1. 美术导入
|
||
a. 在 _Game/Art/UI/Icons/InputKeys/ 下放置按键图标 Sprite Sheet 或单张 PNG
|
||
b. Import Settings:Texture Type = Sprite, Filter=Point, PPU=32(像素图)或 PPU=1(矢量/高分辨率图)
|
||
c. 命名格式:IC_Key_{DeviceShort}_{KeyName}.png
|
||
DeviceShort:KBM(键鼠)/ Xbox / PS / Switch
|
||
示例:IC_Key_KBM_Space.png、IC_Key_Xbox_A.png、IC_Key_PS_Cross.png
|
||
|
||
2. 创建图标集 SO
|
||
a. 菜单 BaseGames/Input Icon Studio → 点击对应设备行的「+ 新建」按钮
|
||
b. 选择保存路径(推荐 _Game/Data/UI/InputIcons/)
|
||
c. 命名:ICN_{DeviceType}.asset(例:ICN_KeyboardMouse.asset、ICN_Xbox.asset)
|
||
|
||
3. 填充图标映射
|
||
a. 在 Input Icon Studio 左列选择 Action,右列指定 Sprite(或在 Inspector 的 InputDeviceIconSetSOEditor 中操作)
|
||
b. 可使用 Inspector 顶部「从 Action Asset 填充路径」按钮批量生成条目,再逐一拖入 Sprite
|
||
c. 覆盖率芯片变为绿色(100%)表示该设备全部 Action 已配置
|
||
|
||
4. 绑定到 InputIconService
|
||
a. 在 Persistent 场景的 UIRoot → InputIconService 组件 Inspector 中
|
||
b. 将 4 个 ICN_*.asset 拖入对应 SerializeField 字段(_kbMouseSet / _xboxSet / _playStationSet / _switchSet)
|
||
|
||
5. 验证
|
||
a. 进入 PlayMode,切换输入设备,观察 HUD 交互提示图标是否正确切换
|
||
b. 在 Input Icon Studio 的「交互提示预览」中模拟检查各设备外观
|
||
```
|
||
|
||
**ICN_ SO 命名与路径规则:**
|
||
|
||
| SO 名称 | 路径 | 对应设备 |
|
||
|---------|------|---------|
|
||
| `ICN_KeyboardMouse.asset` | `_Game/Data/UI/InputIcons/` | 键鼠(`InputDeviceType.KeyboardMouse`) |
|
||
| `ICN_Xbox.asset` | `_Game/Data/UI/InputIcons/` | Xbox 手柄(`InputDeviceType.XboxController`) |
|
||
| `ICN_PlayStation.asset` | `_Game/Data/UI/InputIcons/` | PS4/PS5(`InputDeviceType.PlayStationController`) |
|
||
| `ICN_Switch.asset` | `_Game/Data/UI/InputIcons/` | Switch Pro/Joy-Con(`InputDeviceType.SwitchController`) |
|
||
|
||
**按键图标命名规范(`IC_Key_{DeviceShort}_{KeyName}.png`):**
|
||
|
||
| 设备简称 | 适用范围 | 示例 |
|
||
|---------|---------|------|
|
||
| `KBM` | 键盘按键 / 鼠标按键 | `IC_Key_KBM_Space.png`、`IC_Key_KBM_E.png`、`IC_Key_KBM_LMB.png` |
|
||
| `Xbox` | Xbox 面板按钮 / 摇杆 / 扳机 | `IC_Key_Xbox_A.png`、`IC_Key_Xbox_RT.png`、`IC_Key_Xbox_LStick.png` |
|
||
| `PS` | PlayStation 按钮 / 摇杆 / 扳机 | `IC_Key_PS_Cross.png`、`IC_Key_PS_R2.png`、`IC_Key_PS_L1.png` |
|
||
| `Switch` | Switch 面板按钮 / Joy-Con | `IC_Key_Switch_A.png`、`IC_Key_Switch_ZR.png`、`IC_Key_Switch_DPad.png` |
|
||
|
||
---
|
||
|
||
## 11. 禁止行为清单
|
||
|
||
| 禁止行为 | 原因 | 正确做法 |
|
||
|---------|------|---------|
|
||
| `Resources.Load<T>("path")` | 绕过 Addressables,无法热更 | `AssetLoader.LoadAsync<T>(AddressKeys.Xxx)` |
|
||
| 在代码中硬编码 Address 字符串 | 重构困难,易拼写错误 | 使用 `AddressKeys` 常量 |
|
||
| 直接调用 `Addressables.LoadAssetAsync` | 绕过封装,难以追踪泄漏 | 使用 `AssetLoader.LoadAsync` |
|
||
| 加载后不 Release / 不 Track | 内存泄漏 | `_tracker.Track(handle)` 或显式 Release |
|
||
| 在场景中直接引用动态对象 Prefab | 导致场景与 Prefab 耦合,阻碍动态加载 | Spawner + Addressable Key |
|
||
| 手动修改 `AddressableAssetsData/*.asset` | 破坏 Addressables 内部状态 | 只通过 Groups 窗口 / AddressableBatchTool 操作 |
|
||
| 将 Test 场景注册 Addressable | 污染构建内容 | Test 场景放 `Scenes/Testings/` 并排除于所有 Group |
|
||
| 在同一 Prefab 中跨模块直接引用 SO | 产生跨组依赖,导致资产重复打包 | 通过 Addressables 按需加载配置 SO |
|
||
| 美术和数据混放在同一目录 | 职责不清,影响构建分析 | 美术在 `_Game/Art/`,数据在 `_Game/Data/`,预制体在 `_Game/Prefabs/` |
|
||
| 第三方插件目录内创建自定义资产 | 插件升级时被覆盖 | 自定义内容放在 `_Game/` 下对应模块目录 |
|
||
| 将 `_Game/` 内的资产移到 `Assets/` 根目录 | 破坏第一方/第三方隔离原则 | 所有自有资产必须在 `_Game/` 内 |
|
||
| 将 `AddressableAssetsData/` 移入 `_Game/` | Unity 硬编码此路径,移动后 Addressables 完全失效 | 永远保留在 `Assets/` 根目录 |
|
||
| 绕过编辑器工具手动创建 SO / Prefab | 路径或命名不符合规范,导致 Addressables 工具误报 | 使用 §12 中的对应编辑器窗口创建 |
|
||
|
||
---
|
||
|
||
## 12. 编辑器工具参考
|
||
|
||
所有**资产创建**均应通过以下编辑器工具进行,以保证路径、命名、Addressables 注册完全符合本规范。
|
||
|
||
### 12.1 资产创建工具
|
||
|
||
| 工具名称 | 菜单路径 | 负责资产类型 | 说明 |
|
||
|---------|---------|------------|------|
|
||
| **Character Wizard** | `BaseGames/Data/Character Wizard` | 角色 SO(玩家形态 / Minion / Boss 通用入口) | 统一入口,自动在正确路径创建所有配套 SO,内含快捷跳转按钮 |
|
||
| **Form Editor** | `BaseGames/Data/Form Editor` | 玩家三魂形态(FormSO) | 三栏可视化网格,自动绑定武器/技能引用,支持 TianHun / DiHun / MingHun |
|
||
| **Enemy Data Manager** | `BaseGames/Data/Enemy Data Manager` | 敌人配置 SO(`ENM_*_Stats.asset`)+ 掉落表 | 双面板列表编辑,左栏搜索 + [New],右栏 Stats/Loot 标签 |
|
||
| **Boss Skill Sequence** | `BaseGames/Data/Boss Skill Sequence` | Boss 技能阶段(BossSkillSO / SkillSequenceSO) | Gantt 时间轴可视化,Windup / Active / Recovery 三段颜色标记 |
|
||
| **Skill Editor** | `BaseGames/Data/Skill Editor` | 技能配置 SO(`SKL_*_Data.asset`) | 按 SkillEffectType 分组筛选,右栏含 HitBox 验证 + 资源费预览 |
|
||
| **Weapon Editor** | `BaseGames/Data/Weapon Editor` | 武器配置 SO(`WPN_*_Data.asset`) | 双面板列表,右栏全属性 + HitBox Prefab 验证 + 快捷操作 |
|
||
| **Weapon HitBox Wizard** | `BaseGames/Create/Weapon HitBox Prefab` | 武器 HitBox Prefab(4 方向 Ground/Up/Down/Air) | 自动生成 `WPN_{ID}_HitBox.prefab`,支持各方向碰撞体形状配置 |
|
||
| **Skill HitBox Wizard** | `BaseGames/Create/Skill HitBox Prefab` | 技能 HitBox Prefab(多段伤害支持) | 自动生成 `SKL_{ID}_HitBox.prefab`,可配置 1–4 段 hitBoxCount |
|
||
| **Input Icon Studio** | `BaseGames/Input Icon Studio` | 按键图标集 SO(`ICN_*.asset`)+ 按键图标 Sprite 映射 | 设备标签栏 + Action 列表覆盖率指示 + 实时编辑 + 交互提示模拟预览 |
|
||
|
||
### 12.2 场景搭建工具
|
||
|
||
| 工具名称 | 菜单路径 | 说明 |
|
||
|---------|---------|------|
|
||
| **Boot Flow Wizard** | `BaseGames/Scene/Setup/Boot Flow Wizard` | 4 步启动流程一键配置(事件频道 → Persistent 场景 → MainMenu → 验证) |
|
||
| **Scaffold Persistent Scene** | `BaseGames/Scene/Setup/Scaffold Persistent Scene` | 一键创建 Persistent 场景的 Services/Input/Camera/UI 层次结构 |
|
||
| **Scaffold Main Menu Scene** | `BaseGames/Scene/Setup/Scaffold Main Menu Scene` | 一键创建 MainMenu 场景基础层次结构 |
|
||
| **Scaffold Game Room** | `BaseGames/Scene/Setup/Scaffold Game Room` | 一键创建关卡房间场景基础层次结构 |
|
||
| **Persistent Auto-Loader** | `BaseGames/Scene/Setup/Auto-Open Persistent Scene` | 编辑模式下打开任意场景时自动附加 Persistent(Toggle,仅编辑模式) |
|
||
| **Scene Object Placer** | `BaseGames/Scene/Place/{类型}` | 场景中快速放置角色/陷阱/检查点/摄像机等,自动绑定组件和事件频道 |
|
||
| **Camera Area Setup** | `BaseGames/Scene/Camera Area Setup` | 在当前场景中快速创建并配置摄像机区域 |
|
||
| **Bake All NavSurfaces** | `BaseGames/Scene/Bake All NavSurfaces` (Ctrl+Shift+B) | 一键烘焙场景中所有 NavSurface,仅编辑模式可用 |
|
||
|
||
### 12.3 Addressables 管理工具
|
||
|
||
| 工具名称 | 菜单路径 | 说明 |
|
||
|---------|---------|------|
|
||
| **Rule Sync** | `BaseGames/Addressables/Rule Sync` | 批量扫描/修复分组和标签(基于 `AddressableRules.cs` 规则,支持导出 CSV) |
|
||
| **Addressable Batch Tool** | `BaseGames/Addressables/Addressable Batch Tool` (Alt+Shift+A) | 三标签操作:① 同步 AddressKeys → ② 文件夹批量注册 → ③ Selection 注册 |
|
||
| **Asset Reference Graph** | `BaseGames/Addressables/Asset Reference Graph` | 可视化 Addressable 地址间的引用依赖关系 |
|
||
| **Validate Address Keys** | `BaseGames/Addressables/Validate Address Keys` | 验证 `AddressKeys.cs` 所有常量在 Addressables 中均已注册,构建前自动触发 |
|
||
|
||
### 12.4 事件系统工具
|
||
|
||
| 工具名称 | 菜单路径 | 说明 |
|
||
|---------|---------|------|
|
||
| **Event Bus Monitor** | `BaseGames/Events/Event Bus Monitor` (Ctrl+Shift+E) | 运行时事件派发监控(类型/侦听器数/触发次数实时显示) |
|
||
| **Event Chain Viewer** | `BaseGames/Events/Event Chain Viewer` | 叙事事件链可视化,运行时显示完成/满足/等待状态 |
|
||
| **Create Event Channels** | `BaseGames/Events/Create Event Channels` | 一键生成全局事件频道 SO(幂等,跳过已存在资产) |
|
||
| **Reimport Event Channels** | `BaseGames/Events/Reimport Event Channels` | 重新导入/刷新全局事件频道 SO |
|
||
|
||
### 12.5 工具与维护
|
||
|
||
| 工具名称 | 菜单路径 | 说明 |
|
||
|---------|---------|------|
|
||
| **SO Manager** | `BaseGames/Tools/SO Manager` | 全项目 ScriptableObject 浏览器,支持类型/路径搜索 + Ping |
|
||
| **GM Debug Tool** | `BaseGames/Tools/GM Debug Tool` | 运行时快速注入资源/切换形态/解锁技能(仅 PlayMode) |
|
||
| **Validate All SOs** | `BaseGames/Tools/Validation/Validate All ScriptableObjects` | 扫描所有 `IValidatable` SO 并报告错误(构建前自动触发) |
|
||
| **Apply Script Order** | `BaseGames/Tools/Validation/Apply Script Execution Order Preset` | 将脚本执行顺序预设应用到项目 |
|
||
| **Validate Script Order** | `BaseGames/Tools/Validation/Validate Script Execution Order Preset` | 验证当前脚本执行顺序是否符合预设 |
|
||
| **Missing Scripts (Scene)** | `BaseGames/Tools/Maintenance/Missing Scripts/...` | 在场景/Prefab 中查找或清除 Missing Script 引用 |
|
||
| **Physics2D Layer Matrix** | `BaseGames/Tools/Maintenance/Physics2D Layer Matrix/...` | 检查或自动修复 Physics2D 层碰撞矩阵配置 |
|
||
|
||
> **原则**:新增资产类型时,必须同步在对应编辑器工具中增加创建入口;严禁绕过工具手动在 Project 窗口 "Create" 并手动填写路径/命名,否则将导致 Addressables Rule Sync 工具误报分组或标签不一致。 |