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

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

37 KiB
Raw Blame History

资源文件夹目录规划与管理规范

版本1.1
创建日期2026-05
适用范围Assets/ 目录下所有非代码资源(美术、数据、预制体、场景等)
资源管理系统Unity Addressables禁止使用 Resources.Load
关联文档Architecture/01_ProjectStructure.mdArchitecture/13_AssetPoolModule.md


目录

  1. 为什么使用 _Game/ 父目录
  2. 整体目录结构总览
  3. Art/ 美术资源规范
  4. Data/ ScriptableObject 规范
  5. Prefabs/ 预制体规范
  6. Scenes/ 场景规范
  7. Shaders/ 着色器规范
  8. UI Toolkit/ 规范
  9. Addressables 管理规范
  10. Import Settings 规范
  11. 资源新增工作流
  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
│   │   └── Shared/                     跨模块复用基础资产Palettes、Textures、Materials
│   │
│   ├── Data/                           ScriptableObject 资产(按模块分类)
│   │   ├── Events/                     事件频道 SO按模块分子目录
│   │   ├── Player/
│   │   ├── Combat/
│   │   ├── Enemies/
│   │   ├── Progression/
│   │   ├── Audio/
│   │   ├── World/
│   │   ├── UI/
│   │   └── 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
│   ├── 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.animSkill_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.animAttack01.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
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/                  世界交互事件
│   ├── UI/                     UI 显隐事件
│   ├── 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 面板配置
└── 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
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

3.3 事件频道 SO 特别规则

  • 每个事件频道独立一个文件,禁止在同一 .cs 脚本中定义多个频道类(防止 Script 引用丢失)
  • 文件名与类型名严格对应:EVT_PlayerDied.asset 对应 PlayerDiedEventChannelSO
  • 事件频道 SO 不注册 Addressable,通过 Inspector 直接引用

4. Prefabs/ 预制体规范

4.1 目录结构

Prefabs/
├── Player/                     玩家顶级 Prefab含控制器 / 动画 / 碰撞体AddressablePLY_Player· PLY_Player.prefab
├── Enemies/
│   └── {EnemyID}/              敌人顶级 Prefab含 AI 行为树 / 动画 / 碰撞体AddressableENM_{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.prefabENV_BG_Forest_Far.prefab

4.3 Prefab 嵌套规则

  • Prefab 内的子物件HitBox、HurtBox、骨骼节点不单独注册 Addressable
  • 武器 Prefab 嵌套在角色 Prefab 内时,通过 Nested Prefab 引用,不用 Addressables 动态加载
  • 只有顶级可实例化对象才注册 Addressable 地址

5. Scenes/ 场景规范

5.1 目录结构

Scenes/
├── Persistent.unity            常驻场景,承载全局管理器 PrefabGameManager / 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 场景:只放全局管理器 PrefabSYS_GameManagerSYS_AudioManagerSYS_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 常驻 PrefabGameManager、UIManager 等)、全局配置 SO Local 启动时自动加载
UI 所有 UI PrefabHUD、菜单、弹框等 Local 启动时预加载
Player 玩家 Prefab、武器 Prefab Local 游戏开始时加载
VFX_Common 通用高频特效HitSpark、BloodSplat 等) Local 启动时预加载
Collectibles 收集物 PrefabGeo、Item、HPOrb Local 启动时预加载
Projectiles 抛射物 Prefab Local 启动时预加载
Enemies_{Region} 该区域的敌人 Prefab 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 对象池管理的 PrefabVFX、投射物、收集物等 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 同时有 PoolablePreload 标签)
  • 新增标签前确认是否有批量加载的实际需求,避免标签膨胀(决策流程见 AddressablesLabelSpec.md §6

8.4 AddressKeys.cs 维护流程

文件路径:Assets/_Game/Scripts/Core/Assets/AddressKeys.cs

工作流(添加新资产)

1. 在 Project 中创建/导入资产
2. 在 AddressKeys.cs 中添加对应 const 字符串
3. 在 AddressableBatchTool菜单 BaseGames → Tools → Addressable Batch Tool
   a. 切换到 "① 同步 AddressKeys" 标签
   b. 点击 "Scan" 找到未注册的 Key
   c. 选择目标 Group点击 "Register" 完成注册
4. 运行 AddressKeyValidator菜单 BaseGames → Verification → 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 销毁时显式 ReleasePool 自身管理生命周期)

8.7 Build 策略

构建目标 命令 说明
开发测试 Build > New Build > Default Build Script 全量本地构建,输出到 Library/com.unity.addressables/
内容更新 Build > Update a Previous Build 仅重打修改的 Group需保留上次 catalog
生产发布 CI 流水线触发全量构建 Remote Group 上传 CDNLocal Group 打入安装包

注意AddressableAssetsData/ 目录下的文件由 Unity 自动维护,不得手动修改 .asset 内容,只通过 Addressables Groups 窗口操作。


9. Import Settings 规范

9.1 Sprite / Texture Import 规范

设置项 规范值 说明
Texture Type Sprite (2D and UI) 角色/特效/UI 图
Sprite Mode MultipleSprite SheetSingle 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 角色 2048UI 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 Rate12 fpsPixel Art 动画标准帧率)

9.3 Audio Import 规范

设置项 SFX BGM
Load Type Decompress On Load Streaming
Compression Format Vorbis Vorbis
Quality 70% 60%
Load In Background 关闭 开启

:若使用 FMODAudio 资产由 FMOD Studio 管理Unity 侧只保留 FMOD Bank 引用 SO不直接导入 AudioClip。


10. 资源新增工作流

10.1 新增敌人

1. _Game/Art/Characters/Enemies/ 下创建 {EnemyID}/ 目录,内含 Sprites/ Animations/ Materials/ Atlases/
2. 导入 Sprite Sheet 到 Sprites/,配置 Import SettingsPPU=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. 在 _Game/Data/Enemies/{EnemyID}/ 下创建 ENM_*_Stats.asset 等 SO
8. 在 _Game/Prefabs/Enemies/{EnemyID}/ 下创建 ENM_{Name}.prefab
9. 在 AddressKeys.cs 中添加 PrefabEnemy{Name} 常量
10. 使用 AddressableBatchTool 注册到 Enemies_{Region} 组,添加 Enemy 标签
11. 运行 AddressKeyValidator 验证

10.2 新增 VFX

1. 在 _Game/Art/Effects/Sprites/ 下导入特效 Sprite Sheet配置 Import SettingsPPU=32, Filter=Point
2. 在 _Game/Art/Effects/Materials/ 下创建特效材质
3. 在 _Game/Prefabs/Effects/ 下创建 VFX_{Name}.prefab
4. 在 AddressKeys.cs 中添加 PrefabVFX{Name} 常量
5. 使用 AddressableBatchTool 注册到 VFX_Common 组,添加 Poolable 标签
6. 在 AssetReleaseTracker 配套的 Pool 中注册(纳入对象池)

10.3 新增 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. 使用 AddressableBatchTool 注册到 UI 组

10.4 新增关卡场景

1. 在 _Game/Scenes/ 下创建 Room_{Region}_{Index:D2}.unity
2. 在 AddressKeys.cs 中添加地址常量(复用 SceneRoomPrefix + 动态拼接或新增独立常量)
3. 将场景注册到 Room_{Region} 组
4. 在 _Game/Data/World/Map/ 下创建 MAP_RoomData_{Region}_{Index:D2}.asset

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/ 根目录