文档目标: 终结“按类型放”还是“按模块放”的争论。 核心结论: 采用 “混合式架构” (Hybrid Approach)。底层通用资源按类型,上层业务逻辑按模块。
Assets/Scripts/Player/PlayerController.csAssets/Prefabs/Player/Player.prefabAssets/Textures/Player/Skin.pngAssets/Features/Player/
Scripts/Prefabs/Art/Player 文件夹,整个功能就删干净了。这是适用于中大型(塔防/RPG)项目的标准结构。
Assets/
├── _Project/ # 🔒 核心开发区 (加下划线置顶)
│ ├── Art/ # 🎨 通用美术资源 (被多个模块复用的)
│ │ ├── Animations/
│ │ ├── Materials/ # 通用材质 (如全屏后处理)
│ │ ├── Models/ # 环境、建筑等静态模型
│ │ ├── Shaders/
│ │ ├── Textures/ # 地面、天空盒
│ │ └── UI/ # 通用 UI (按钮、窗口底板、通用图标)
│ │
│ ├── Audio/ # 🔊 音频资源
│ │ ├── BGM/
│ │ └── SFX/ # 通用音效 (UI点击、升级成功)
│ │
│ ├── Core/ # 🧠 核心框架 (不依赖具体玩法)
│ │ ├── AudioSystem/
│ │ ├── EventSystem/
│ │ ├── SaveSystem/
│ │ └── UIManager/
│ │
│ ├── Features/ # 🧩 玩法模块 (按功能切分 - 最重要!)
│ │ ├── Enemies/ # 敌人模块
│ │ │ ├── Bosses/
│ │ │ ├── Minions/
│ │ │ └── EnemySpawner.cs
│ │ ├── Towers/ # 塔模块
│ │ │ ├── ArcherTower/ # 包含该塔的 Prefab, Script, 独有贴图
│ │ │ └── MagicTower/
│ │ ├── Player/ # 玩家模块
│ │ └── Inventory/ # 背包系统
│ │
│ ├── Scenes/ # 🎬 场景文件
│ │ ├── Boot.unity # 启动场景
│ │ ├── Menu.unity
│ │ └── Levels/
│ │
│ └── Resources/ # 🚫 慎用!仅放 Logo 或 Loading 预制体
│
├── Plugins/ # 🔌 第三方插件 (DoTween, Odin, Sirenix)
├── StreamingAssets/ # 🌊 流式资源 (视频、热更包)
└── Editor/ # 🛠️ 存放编辑器工具脚本 (AssetNamingValidator.cs)
_Project (根目录隔离)为什么要这一层?
当你从 Asset Store 下载插件时,它们通常会直接安装在 Assets 根目录下。如果你把自己的代码也放在 Assets 根目录下,很快你的文件就会和插件文件混在一起。
_Project(或 _Game)里。Assets 根目录只留给插件和系统文件夹。Features (特性/模块目录)这是“按模块放”哲学的核心。
Features/Towers/FireTower/ 里面,而不是 Art/Textures 里面。Features/[ModuleName]/_Project/Art/ 或 _Project/Audio/Art vs Features很多美术同学习惯按 Art/Characters, Art/Weapons 提交资源。
Art 文件夹作为“仓库”。美术提交的原始模型、贴图放在这里。Features 文件夹作为“组装车间”。程序在这里制作 Prefab。Art 里的模型。StreamingAssets.json, .xml)。.mp4)。Assets/Player.csAssets/MyGameScript.csAssets/Resources/Textures/All_Game_Textures...Assets/Script (单数)Assets/Prefabs (复数).keep 文件。你可以写一个简单的 Editor 脚本,在项目初始化时自动创建这些文件夹,保证所有团队成员的结构一致。
// 放在 Assets/Editor/ProjectSetup.cs
[MenuItem("Tools/Setup Project Folders")]
public static void CreateFolders() {
string root = "Assets/_Project";
Directory.CreateDirectory($"{root}/Art");
Directory.CreateDirectory($"{root}/Audio");
Directory.CreateDirectory($"{root}/Code");
Directory.CreateDirectory($"{root}/Features");
Directory.CreateDirectory($"{root}/Scenes");
AssetDatabase.Refresh();
}