chore: initial commit

This commit is contained in:
2026-05-08 11:04:00 +08:00
commit f55d2a57c3
6278 changed files with 866081 additions and 0 deletions

View File

@@ -0,0 +1,473 @@
# 01 · 项目结构与规范
> **作用**定义文件夹布局、Assembly Definition 清单、命名规范、ScriptableObject 资产路径、代码风格约束。
> **所有程序员必读**,开始任何模块开发前先阅读本文档。
---
## 目录
1. [文件夹布局](#1-文件夹布局)
2. [Assembly Definitionsasmdef](#2-assembly-definitions)
3. [命名规范](#3-命名规范)
4. [ScriptableObject 资产组织](#4-scriptableobject-资产组织)
5. [Addressables 资产组织](#5-addressables-资产组织)
6. [代码风格约束](#6-代码风格约束)
7. [Prefab 组织规范](#7-prefab-组织规范)
8. [场景组织规范](#8-场景组织规范)
---
## 1. 文件夹布局
```
Assets/
├── Scripts/ ← 所有游戏代码(按模块分文件夹)
│ ├── Core/ BaseGames.Core + BaseGames.Core.Events
│ │ ├── Events/ SO 事件频道类型
│ │ └── Save/ SaveManager + ISaveStorage + SaveData
│ ├── Input/ BaseGames.Input
│ ├── Camera/ BaseGames.Camera
│ ├── Player/ BaseGames.Player
│ │ └── States/ BaseGames.Player.States
│ ├── Combat/ BaseGames.Combat
│ │ └── StatusEffects/ BaseGames.Combat.StatusEffects
│ ├── Parry/ BaseGames.Parry
│ ├── Enemies/ BaseGames.Enemies
│ │ ├── AI/ BaseGames.Enemies.AIBehavior Designer Tasks
│ │ ├── Boss/
│ │ │ └── Patterns/ BaseGames.Enemies.Boss.Patterns
│ │ └── Navigation/ BaseGames.Enemies.Navigation
│ ├── Feedback/ BaseGames.Feedback
│ ├── World/ BaseGames.World
│ │ ├── Map/ BaseGames.World.Map
│ │ └── Shop/ BaseGames.World.Shop
│ ├── UI/ BaseGames.UI
│ ├── Audio/ BaseGames.Audio
│ ├── Progression/ BaseGames.Progression
│ ├── Dialogue/ BaseGames.Dialogue
│ ├── Equipment/ BaseGames.Equipment
│ ├── Cutscene/ BaseGames.Cutscene
│ ├── Animation/ BaseGames.Animation
│ ├── Spells/ BaseGames.Spells
│ ├── Localization/ BaseGames.Localization
│ ├── Tutorial/ BaseGames.Tutorial
│ ├── Platform/ BaseGames.Platform
│ └── Editor/ BaseGames.EditorEditor Only
├── Data/ ← ScriptableObject 资产(按模块分文件夹)
│ ├── Events/ 所有事件频道 SO
│ ├── Player/ PlayerStatsSO、PlayerMovementConfigSO 等
│ ├── Combat/ WeaponSO、ProjectileConfigSO 等
│ ├── Enemies/ EnemyStatsSO、AttackPatternSO 等
│ ├── Progression/ SkillSO、CharmSO、AbilityConfigSO 等
│ ├── Audio/ AudioCueSO、BGMPlaylistSO 等
│ ├── World/ MapRoomDataSO、ShopInventorySO 等
│ ├── UI/ UIConfigSO 等
│ └── Settings/ GlobalSettingsSO
├── Prefabs/ ← 预制体
│ ├── Player/
│ ├── Enemies/
│ ├── World/
│ ├── UI/
│ ├── Combat/ HitBox、HurtBox、Projectile 等
│ ├── Effects/ VFX Prefabs
│ └── Persistent/ Persistent 场景专用 Prefabs
├── Scenes/
│ ├── Persistent.unity 常驻场景
│ ├── MainMenu.unity
│ ├── Room_*/ 各关卡房间场景
│ └── Boss_*/ Boss 战场景
├── Art/ 美术资源(不在此文档范围)
├── Audio/ 音频资源FMOD 项目)
└── StreamingAssets/ FMOD 音频包等
```
---
## 2. Assembly Definitions
所有 asmdef 均位于对应的 `Scripts/` 子文件夹下,文件名与程序集名称一致。
### 依赖层次(底层 → 上层)
```
BaseGames.Core.Events
└─→ BaseGames.Core
├─→ BaseGames.Input
├─→ BaseGames.Camera
├─→ BaseGames.Audio
├─→ BaseGames.Localization
├─→ BaseGames.Platform
├─→ BaseGames.World
│ └─→ BaseGames.World.Map
│ └─→ BaseGames.World.Shop
└─→ BaseGames.Combat
├─→ BaseGames.Parry
├─→ BaseGames.Combat.StatusEffects
└─→ BaseGames.Player
├─→ BaseGames.Player.States
├─→ BaseGames.Progression
├─→ BaseGames.Equipment
├─→ BaseGames.Spells
└─→ BaseGames.Enemies
├─→ BaseGames.Enemies.AI
├─→ BaseGames.Enemies.Navigation
└─→ BaseGames.Enemies.Boss.Patterns
BaseGames.Feedback依赖Core.Events、Player、Enemies
BaseGames.Animation依赖Core.Events、Player
BaseGames.UI依赖Core.Events、Core、Progression
BaseGames.Dialogue依赖Core.Events、UI
BaseGames.Cutscene依赖Core.Events、UI、Dialogue
BaseGames.Tutorial依赖Core.Events、Progression
BaseGames.EditorEditor Only依赖全部运行时程序集
```
### asmdef 文件清单
| 文件名 | 程序集名称 | 编辑器 | 关键外部引用 |
|--------|----------|--------|------------|
| `BaseGames.Core.Events.asmdef` | `BaseGames.Core.Events` | ✗ | — |
| `BaseGames.Core.asmdef` | `BaseGames.Core` | ✗ | `Newtonsoft.Json` |
| `BaseGames.Input.asmdef` | `BaseGames.Input` | ✗ | `Unity.InputSystem` |
| `BaseGames.Camera.asmdef` | `BaseGames.Camera` | ✗ | `Cinemachine` |
| `BaseGames.Audio.asmdef` | `BaseGames.Audio` | ✗ | `FMODUnity`(可选) |
| `BaseGames.Localization.asmdef` | `BaseGames.Localization` | ✗ | `Unity.Localization` |
| `BaseGames.Platform.asmdef` | `BaseGames.Platform` | ✗ | `Steamworks.NET`(条件编译) |
| `BaseGames.Combat.asmdef` | `BaseGames.Combat` | ✗ | — |
| `BaseGames.Combat.StatusEffects.asmdef` | `BaseGames.Combat.StatusEffects` | ✗ | — |
| `BaseGames.Parry.asmdef` | `BaseGames.Parry` | ✗ | — |
| `BaseGames.World.asmdef` | `BaseGames.World` | ✗ | — |
| `BaseGames.World.Map.asmdef` | `BaseGames.World.Map` | ✗ | — |
| `BaseGames.World.Shop.asmdef` | `BaseGames.World.Shop` | ✗ | — |
| `BaseGames.Player.asmdef` | `BaseGames.Player` | ✗ | `Kybernetik.Animancer` |
| `BaseGames.Player.States.asmdef` | `BaseGames.Player.States` | ✗ | `Kybernetik.Animancer` |
| `BaseGames.Progression.asmdef` | `BaseGames.Progression` | ✗ | — |
| `BaseGames.Equipment.asmdef` | `BaseGames.Equipment` | ✗ | — |
| `BaseGames.Spells.asmdef` | `BaseGames.Spells` | ✗ | — |
| `BaseGames.Enemies.asmdef` | `BaseGames.Enemies` | ✗ | `Kybernetik.Animancer` |
| `BaseGames.Enemies.AI.asmdef` | `BaseGames.Enemies.AI` | ✗ | `BehaviorDesigner.Runtime` |
| `BaseGames.Enemies.Navigation.asmdef` | `BaseGames.Enemies.Navigation` | ✗ | `PathBerserker2d` |
| `BaseGames.Enemies.Boss.Patterns.asmdef` | `BaseGames.Enemies.Boss.Patterns` | ✗ | — |
| `BaseGames.Feedback.asmdef` | `BaseGames.Feedback` | ✗ | `MoreMountains.Tools`, `MoreMountains.Feedbacks` |
| `BaseGames.Animation.asmdef` | `BaseGames.Animation` | ✗ | `Kybernetik.Animancer` |
| `BaseGames.UI.asmdef` | `BaseGames.UI` | ✗ | — |
| `BaseGames.Dialogue.asmdef` | `BaseGames.Dialogue` | ✗ | `Unity.Localization` |
| `BaseGames.Cutscene.asmdef` | `BaseGames.Cutscene` | ✗ | `Unity.Timeline` |
| `BaseGames.Tutorial.asmdef` | `BaseGames.Tutorial` | ✗ | — |
| `BaseGames.Editor.asmdef` | `BaseGames.Editor` | ✓ | 所有运行时程序集 |
---
## 3. 命名规范
### 类型名称
| 类型 | 后缀 / 规则 | 示例 |
|------|-----------|------|
| MonoBehaviour 组件 | 无后缀 | `PlayerController``EnemyBase` |
| ScriptableObject | `SO` 后缀 | `PlayerStatsSO``ShopItemSO` |
| 事件频道 SO | `EventChannelSO` 后缀 | `VoidEventChannelSO``IntEventChannelSO` |
| 接口 | `I` 前缀 | `ISaveable``IInteractable``ICharmEffect` |
| 枚举 | PascalCase 无后缀 | `GameState``AbilityType``DamageType` |
| 泛型基类 | `Base` 后缀 | `PlayerStateBase``EnemyStateBase` |
| Editor 扩展 | `Editor` 后缀 | `PlayerControllerEditor``EnemyBaseEditor` |
| 协程方法 | `Coroutine` 后缀 | `LoadSceneCoroutine()``DeathSequenceCoroutine()` |
### 字段命名
```csharp
// 私有序列化字段_camelCase下划线前缀
[SerializeField] private PlayerMovementConfigSO _movementConfig;
// 私有非序列化字段_camelCase
private float _currentSpeed;
// 属性PascalCase
public float CurrentSpeed => _currentSpeed;
// 常量ALL_CAPS
private const float MAX_SPEED = 10f;
// 局部变量camelCase
float deltaSpeed = targetSpeed - _currentSpeed;
```
### 文件命名
| 类型 | 规则 | 示例 |
|------|------|------|
| C# 脚本 | 与类名完全一致 | `PlayerController.cs` |
| SO 资产 | `[SystemPrefix]_[Name]` | `PLY_Stats_Default.asset``EVT_PlayerDied.asset` |
| Prefab | `[SystemPrefix]_[Name]` | `PLY_Player.prefab``ENM_GruntWarrior.prefab` |
| 场景 | `Room_{Region}_{Index:D2}` | `Room_Forest_01.unity` |
| asmdef | 与程序集名称一致 | `BaseGames.Player.asmdef` |
### SO 资产前缀表
| 前缀 | 系统 |
|------|------|
| `EVT_` | 事件频道 |
| `PLY_` | 玩家配置 |
| `CMB_` | 战斗配置 |
| `ENM_` | 敌人配置 |
| `WPN_` | 武器配置 |
| `SKL_` | 技能 / 法术 |
| `CHM_` | 护身符 |
| `SHP_` | 商店 |
| `MAP_` | 地图 |
| `AUD_` | 音频 |
| `UI_` | UI 配置 |
| `SET_` | 设置 |
---
## 4. ScriptableObject 资产组织
### 目录结构(`Assets/Data/`
```
Assets/Data/
├── Events/
│ ├── Core/ EVT_GameStateChanged.asset, EVT_SceneLoadRequest.asset …
│ ├── Player/ EVT_PlayerDied.asset, EVT_HPChanged.asset …
│ ├── Combat/ EVT_DamageDealt.asset …
│ ├── World/ EVT_RoomTransition.asset …
│ └── UI/ EVT_ShowPanel.asset …
├── Player/
│ ├── PLY_Stats_Default.asset
│ ├── PLY_MovementConfig.asset
│ ├── PLY_AnimConfig.asset
│ └── PLY_FormConfig.asset
├── Combat/
│ ├── CMB_WeaponBase.asset
│ └── CMB_ProjectileConfig_*.asset
├── Enemies/
│ ├── ENM_Stats_*.asset
│ └── ENM_AttackPattern_*.asset
├── Progression/
│ ├── SKL_SoulSpell_*.asset
│ ├── CHM_Charm_*.asset
│ └── ABL_AbilityConfig_*.asset
├── Audio/
│ ├── AUD_BGMPlaylist_*.asset
│ └── AUD_SFXCue_*.asset
├── World/
│ ├── MAP_RoomData_*.asset
│ └── SHP_ShopInventory_*.asset
└── Settings/
└── SET_GlobalSettings.asset
```
---
## 5. Addressables 资产组织
### AddressKeys 静态类(路径:`Scripts/Core/AddressKeys.cs`
```csharp
// 路径: Assets/Scripts/Core/Assets/AddressKeys.cs
// ⚠️ 命名规范:驼峰式,无下划线分隔(`PrefabPlayer` 不是 `Pfx_Player_Main`
// 地址值与 Addressables Groups 窗口 Address 列保持完全一致
namespace BaseGames.Core
{
public static class AddressKeys
{
// ── Scenes ──────────────────────────────────────────────
public const string ScenePersistent = "Scene_Persistent";
public const string SceneMainMenu = "Scene_MainMenu";
public const string SceneRoomPrefix = "Room_";
public const string SceneBossPrefix = "Boss_";
// ── Player ──────────────────────────────────────────────
public const string PrefabPlayer = "PLY_Player";
// ── UI ──────────────────────────────────────────────────
public const string PrefabUIHUD = "UI_HUD";
public const string PrefabUIPauseMenu = "UI_PauseMenu";
public const string PrefabUIDeathScreen = "UI_DeathScreen";
public const string PrefabUILoadingScreen = "UI_LoadingScreen";
// ── VFX ─────────────────────────────────────────────────
public const string PrefabVFXHitSpark = "VFX_HitSpark";
public const string PrefabVFXDeathBurst = "VFX_DeathBurst";
public const string PrefabVFXParryFlash = "VFX_ParryFlash";
// ── Audio ────────────────────────────────────────────────
public const string PrefabAudioMasterMixer = "MasterMixer";
// ── Labels用于 Addressables.LoadAssetsAsync 批量加载)───
public const string LabelEnemy = "Enemy";
public const string LabelPoolable = "Poolable";
public const string LabelBGM = "BGM";
public const string LabelCharms = "Charms";
}
}
```
> **完整 `AddressKeys` 定义见 `13_AssetPoolModule.md §2`**,本节仅展示命名约定示例。
### Addressables 分组策略
| 组名 | 内容 | 加载时机 |
|------|------|---------|
| `DefaultLocalGroup` | 常驻资源GameManager Prefab、HUD 等) | 启动时预加载 |
| `Room_{Region}` | 各区域房间所有资产 | 进入区域时加载 |
| `Boss_{Name}` | Boss 战专属资产 | Boss 战开始前加载 |
| `UI` | 所有 UI Prefab | 启动时预加载 |
| `VFX_Common` | 通用特效 | 启动时预加载 |
| `Audio_Music` | BGMFMOD 包) | 按需加载 |
---
## 6. 代码风格约束
### 禁止模式
```csharp
// ❌ 禁止FindObjectOfType
var player = FindObjectOfType<PlayerController>();
// ❌ 禁止:跨 GameObject GetComponent组件不在同一 Prefab 内)
var stats = otherGO.GetComponent<PlayerStats>();
// ❌ 禁止:静态单例暴露子系统
public static AudioManager Instance { get; private set; } // 禁止全局访问
// ❌ 禁止Resources.Load
var sprite = Resources.Load<Sprite>("Enemies/goblin");
// ❌ 禁止:跨系统 Inspector 序列化引用
[SerializeField] private PlayerController _player; // 在 EnemyBase 中引用玩家 ❌
// ❌ 禁止:硬编码 Addressable 字符串
var handle = Addressables.LoadAsset<GameObject>("PLY_Player"); // ❌ 用 AddressKeys 常量
```
### 推荐模式
```csharp
// ✅ SO 事件频道(跨模块通信)
[SerializeField] private VoidEventChannelSO _onPlayerDied;
private void OnEnable() => _onPlayerDied.OnEventRaised += HandlePlayerDied;
private void OnDisable() => _onPlayerDied.OnEventRaised -= HandlePlayerDied;
// ✅ Inspector 序列化(同 Prefab 内)
[SerializeField] private PlayerMovement _movement; // 在 PlayerController 中 ✅
// ✅ Addressables 加载
Addressables.InstantiateAsync(AddressKeys.PrefabPlayer).Completed += OnPlayerLoaded;
// ✅ 对象池
GlobalObjectPool.Instance.Spawn<HitEffect>(AddressKeys.PrefabVFXHitSpark, position, rotation);
```
### OnEnable / OnDisable 规则
每个订阅 SO 事件频道的组件**必须**在 `OnDisable` 中取消订阅,防止内存泄漏:
```csharp
private void OnEnable()
{
_channel.OnEventRaised += HandleEvent;
}
private void OnDisable()
{
_channel.OnEventRaised -= HandleEvent;
}
```
---
## 7. Prefab 组织规范
### Player Prefab 层级
```
[PLY_Player] ← PlayerController协调器
├── PlayerMovement ← Rigidbody2D 封装
├── PlayerStats ← 属性容器
├── PlayerCombat ← 攻击逻辑
├── FormController ← 形态管理
├── WeaponManager ← 武器切换
├── SkillManager ← 技能执行
├── SpringSystem ← 灵泉管理
├── ParrySystem ← 弹反逻辑
├── AnimancerComponent ← Animancer 入口
├── PlayerFeedback ← MMF_Player
├── HurtBox ← Composite Collider 受击区域
├── HitBox_Ground ← BoxCollider2D 地面攻击判定
├── HitBox_Up ← BoxCollider2D 上劈判定
├── HitBox_Down ← BoxCollider2D 下劈判定
├── HitBox_Air ← BoxCollider2D 空中判定
└── SpriteRenderer
```
### Enemy Prefab 通用层级
```
[ENM_{EnemyName}] ← EnemyBase协调器+ BehaviorTree
├── EnemyMovement ← PathBerserker2d EnemyNavAgent 封装
├── EnemyStats ← HP/攻击等属性
├── EnemyCombat ← HitBox 管理
├── AnimancerComponent ← 动画
├── EnemyFeedback ← MMF_Player
├── HurtBox ← 受击区域
└── HitBox_{N} ← 各攻击 HitBox
```
---
## 8. 场景组织规范
### 场景文件命名
```
Persistent ← 常驻场景GameManager、AudioManager 等单例)
MainMenu ← 主菜单
Room_{Region}_{Index:D2} ← 关卡房间 例: Room_Forest_01
Boss_{Region} ← Boss 战 例: Boss_Forest
Hub_Town ← 区域枢纽 例: Hub_RestCamp
```
### 房间场景层级结构
```
Scene: Room_{Region}_{Index}
├── [Level]
│ ├── Tilemap_Ground
│ ├── Tilemap_Background
│ ├── Tilemap_Foreground
│ ├── Tilemap_OneWay
│ └── Tilemap_Destructible
├── [NavMesh]
│ ├── NavSurface
│ └── NavLink_{N}
├── [Enemies]
│ └── Enemy_*Prefab 实例)
├── [World]
│ ├── RoomTransition_{Direction}
│ ├── SavePoint可选
│ └── Collectible_*
├── [Camera]
│ ├── CinemachineVirtualCamera
│ └── CameraConfinerPolygonCollider2D
└── [Lighting]
└── GlobalLight2D
```
### Persistent 场景组织
```
Scene: Persistent
├── GameManager ← DontDestroyOnLoad 协调器
├── AudioManager ← FMOD 封装
├── ObjectPoolManager ← 对象池
├── SettingsManager ← 设置管理
└── InputReader ← InputReaderSO持久化
```