Files
zeling_v2/Docs/Architecture/01_ProjectStructure.md
2026-05-08 11:04:00 +08:00

19 KiB
Raw Permalink Blame History

01 · 项目结构与规范

作用定义文件夹布局、Assembly Definition 清单、命名规范、ScriptableObject 资产路径、代码风格约束。
所有程序员必读,开始任何模块开发前先阅读本文档。


目录

  1. 文件夹布局
  2. Assembly Definitionsasmdef
  3. 命名规范
  4. ScriptableObject 资产组织
  5. Addressables 资产组织
  6. 代码风格约束
  7. Prefab 组织规范
  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 组件 无后缀 PlayerControllerEnemyBase
ScriptableObject SO 后缀 PlayerStatsSOShopItemSO
事件频道 SO EventChannelSO 后缀 VoidEventChannelSOIntEventChannelSO
接口 I 前缀 ISaveableIInteractableICharmEffect
枚举 PascalCase 无后缀 GameStateAbilityTypeDamageType
泛型基类 Base 后缀 PlayerStateBaseEnemyStateBase
Editor 扩展 Editor 后缀 PlayerControllerEditorEnemyBaseEditor
协程方法 Coroutine 后缀 LoadSceneCoroutine()DeathSequenceCoroutine()

字段命名

// 私有序列化字段_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.assetEVT_PlayerDied.asset
Prefab [SystemPrefix]_[Name] PLY_Player.prefabENM_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

// 路径: 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. 代码风格约束

禁止模式

// ❌ 禁止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 常量

推荐模式

// ✅ 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 中取消订阅,防止内存泄漏:

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持久化