- Add RoomStreamingManager to manage room loading and unloading based on player proximity. - Create StreamingBudgetConfigSO for memory and performance budgeting of the streaming system. - Introduce TransitionDirector to handle seamless and atmospheric fade transitions between rooms. - Develop WorldGraph to represent room connectivity and facilitate neighbor queries and distance calculations. - Implement RoomNode and RoomEdge classes to structure room data and connections.
52 KiB
资源文件夹目录规划与管理规范
版本:1.3
创建日期:2026-05
适用范围:Assets/目录下所有非代码资源(美术、数据、预制体、场景等)
资源管理系统:Unity Addressables(禁止使用Resources.Load)
关联文档:Architecture/01_ProjectStructure.md、Architecture/13_AssetPoolModule.md
目录
- 为什么使用
_Game/父目录 - 整体目录结构总览
- Art/ 美术资源规范
- Data/ ScriptableObject 规范
- Prefabs/ 预制体规范
- Scenes/ 场景规范
- Shaders/ 着色器规范
- UI Toolkit/ 规范
- Addressables 管理规范
- Import Settings 规范
- 资源新增工作流
- 禁止行为清单
- 编辑器工具参考
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/ 商店配置
├── Streaming/ 流式加载配置(StreamingBudgetConfigSO)
├── 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 |
STR_ |
流式加载配置 | STR_BudgetConfig_Default.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 实例化规则
// ✅ 推荐:通过 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(含 STR_BudgetConfig_Default、Config/FootstepCatalog 等) |
Local | 按需加载 |
划分原则:
- 生命周期相同的资源放同一组——一起加载、一起卸载
- 不同区域的资源绝对隔离——防止 Region A 的资产随 Region B 打包
- 高频小资产合入 Common 组——避免大量小 handle 的运行时开销
- 场景文件与其依赖资产放同一组——确保 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
Config/StreamingBudgetConfig
强制要求:所有 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
// ✅ 正确:使用 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:
12fps(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 工具误报分组或标签不一致。