515 lines
41 KiB
Markdown
515 lines
41 KiB
Markdown
# 开发实施计划
|
||
|
||
> **版本**:1.0
|
||
> **日期**:2026-05-11
|
||
> **依据**:`Docs/Architecture/`(24 份架构文档)
|
||
> **目标**:完整实现 `Docs/Design/` 所有技术需求
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [策略选择](#1-策略选择)
|
||
2. [整体阶段概览](#2-整体阶段概览)
|
||
3. [Phase 0:项目基础](#3-phase-0项目基础)
|
||
4. [Phase 1:垂直切片 MVP](#4-phase-1垂直切片-mvp)
|
||
5. [Phase 2:核心玩法扩展](#5-phase-2核心玩法扩展)
|
||
6. [Phase 3:世界与进程系统](#6-phase-3世界与进程系统)
|
||
7. [Phase 4:内容与完善](#7-phase-4内容与完善)
|
||
8. [模块依赖顺序](#8-模块依赖顺序)
|
||
9. [技术风险与缓解策略](#9-技术风险与缓解策略)
|
||
|
||
---
|
||
|
||
## 1. 策略选择
|
||
|
||
### 为什么不用纯 MVP 先验证可行性?
|
||
|
||
纯 MVP 策略适合**架构未定型**的项目——先做最小功能,验证架构方向再继续。
|
||
|
||
本项目**架构已完全定型**(24 份文档,类/接口/字段/方法全部明确),逻辑设计无需验证。真正的风险集中在:
|
||
|
||
| 风险点 | 内容 |
|
||
|--------|------|
|
||
| 第三方库集成 | Animancer Pro FSM、PathBerserker2d NavSurface、Behavior Designer AI 树三者协作 |
|
||
| SO 事件频道跨系统串联 | 首次接线需要验证整条链路(Input→Player→Combat→Save→UI) |
|
||
| Addressables 异步加载 | 场景 Additive 加载 + Persistent 常驻场景的 Load/Unload 时序 |
|
||
| Cinemachine + PixelPerfect | 相机切换与房间边界的实际表现 |
|
||
|
||
### 推荐:骨架垂直切片策略
|
||
|
||
```
|
||
Phase 0: 项目骨架(无可玩内容,但基础设施就绪)
|
||
↓
|
||
Phase 1: 垂直切片 MVP(一个可玩房间,验证所有第三方集成点)
|
||
↓
|
||
Phase 2: 核心玩法扩展(在验证的骨架上填充完整战斗/移动系统)
|
||
↓
|
||
Phase 3: 世界与进程系统(地图、存档、谜题、任务)
|
||
↓
|
||
Phase 4: 内容与完善(Boss 技能、叙事、支撑系统、平台发布)
|
||
```
|
||
|
||
每个 Phase 结束都有**可演示的里程碑**,但 Phase 0 之后的每一层都是在可运行的代码上追加,而非重写。
|
||
|
||
---
|
||
|
||
## 2. 整体阶段概览
|
||
|
||
| Phase | 目标 | 里程碑 | 预估周期 | 状态 |
|
||
|-------|------|--------|---------|------|
|
||
| **0** | 项目基础设施 | 编译无错,基础框架可寻址加载 | 1 周 | ✅ 完成(2026-05-07)|
|
||
| **1** | 垂直切片 MVP | 一个房间可玩:移动/攻击/一只敌人/存读档 | 3–4 周 | ✅ 完成(2026-05-08)|
|
||
| **2** | 核心玩法扩展 | 完整玩家能力树/战斗系统/多种敌人 | 4–5 周 | 🔄 代码全部完成(剩余:VFX 资产填充 - 仅 Unity 编辑器操作)|
|
||
| **3** | 世界与进程 | 完整地图/谜题/任务/商店 | 4–5 周 | ✅ 代码全部完成(剩余:P3-1 Prefab 装配 - 仅 Unity 编辑器操作)|
|
||
| **4** | 内容与完善 | Boss/叙事/平台服务/QA | 3–4 周 | ✅ 完成(2026-05-11,P4-1~P4-6 全部 ✅)|
|
||
|
||
---
|
||
|
||
## 3. Phase 0:项目基础
|
||
|
||
**目标**:所有模块能编译,Addressables/Assembly Definitions/SO 事件频道骨架就绪,无可玩内容。
|
||
|
||
### 任务清单
|
||
|
||
#### P0-1:项目结构(01_ProjectStructure)
|
||
- [x] 按规范建立 `Assets/Scripts/`、`Assets/Data/`、`Assets/Prefabs/`、`Assets/Scenes/` 文件夹层级
|
||
- [x] 创建全部 Assembly Definition 文件(`BaseGames.Core`、`BaseGames.Core.Events`、`BaseGames.Core.Save`、`BaseGames.Input`、`BaseGames.Player`、`BaseGames.Player.States`、`BaseGames.Combat`、`BaseGames.Combat.StatusEffects`、`BaseGames.Parry`、`BaseGames.Enemies`、`BaseGames.Enemies.AI`、`BaseGames.World`、`BaseGames.UI`、`BaseGames.Audio`、`BaseGames.Progression`、`BaseGames.Feedback`、`BaseGames.Camera`、`BaseGames.Animation`、`BaseGames.Editor`)
|
||
- [x] 验证 asmdef 依赖方向(低层不引用高层,`Core.Events` 无任何依赖)
|
||
- [x] 建立 `Persistent.unity` 场景骨架(空 GameObject 层级,待 Phase 1 填充组件)
|
||
|
||
#### P0-2:SO 事件系统(02_EventSystem)
|
||
- [x] `BaseEventChannelSO<T>` 泛型基类
|
||
- [x] `VoidBaseEventChannelSO` 无负载基类
|
||
- [x] 所有具体频道类型(已创建):`VoidEventChannelSO`、`IntEventChannelSO`、`FloatEventChannelSO`、`BoolEventChannelSO`、`StringEventChannelSO`、`Vector2EventChannelSO`、`TransformEventChannelSO`、`GameStateEventChannelSO`、`SceneLoadRequestEventChannelSO`、`DifficultyChangedEventChannel`、`DamageInfoEventChannelSO`、`HitConfirmedEventChannelSO`、`ShopPurchaseEventChannelSO`、`DialogueEventChannelSO`、`LiquidEventChannelSO`、`WorldMarkerEventChannelSO`、`AbilityTypeEventChannelSO`(`AbilityType` payload)、`ColorBlindModeEventChannelSO`、`BossSkillEventChannelSO`、`BossPhaseEventChannelSO`、`StatusEffectEventChannelSO`、`QuestStateChangedEventChannel`、`QuestObjectiveEventChannelSO`
|
||
- [x] `ToolUsedEventChannelSO`(payload:`ToolUsedPayload { SlotIndex, ToolId }`;`Core/Events/ToolEvents.cs`;⚠️ 架构 09 §7.5 用 `Tool` 对象,实现用 `string ToolId` 避免跨程序集依赖)
|
||
- [x] `AchievementEventChannelSO`(payload:`AchievementSO`;`Progression/AchievementSO.cs`;Phase 0 骨架,Phase 4 扩充)
|
||
- [x] 在 `Assets/Data/Events/` 下预建所有全局频道 `.asset` 资产(`CreateEventChannelAssets` Editor 菜单一键生成;对照 `02_EventSystem §4` 清单)
|
||
- [x] `EventSubscription` struct + `CompositeDisposable`(已实现;命名差异:架构用 `EventSubscriptionToken`/`DisposableSubscription`,实现用 `EventSubscription`/`CompositeDisposable`——功能等价)
|
||
- [x] `AddTo(ICollection<IDisposable>)` 扩展方法(`EventSubscriptionExtensions` 静态类;架构 02 §8)
|
||
|
||
#### P0-3:Core 骨架(03_CoreModule)
|
||
- [x] `GameStateId` struct + `IGameState` 接口 + `GameStateMachine`(替代旧 `GameState` 枚举;架构 03_CoreModule §2)
|
||
- [x] `GameStates` 静态工厂(8 个内置状态:MainMenu/Gameplay/Paused/BossFight/Cutscene/Loading/Dead/GameOver)
|
||
- [x] `IGameStateFactory` 接口(供 DLC/扩展注册自定义状态)
|
||
- [x] `GameStateEventChannelSO` payload 类型为 `GameStateId`(非旧 enum)
|
||
- [x] `GameManager`(字段 + 接口签名,Awake 暂留空,内嵌 `GameStateMachine`)
|
||
- [x] `SceneLoader`(异步加载骨架,`LoadSceneAsync` 封装)
|
||
- [x] `SettingsManager` + `GlobalSettingsSO`
|
||
- [x] `GlobalObjectPool`(通用池,`Spawn<T>` / `Despawn`;`WarmupAsync` 批量预热)
|
||
- [x] `PooledObject` 组件
|
||
|
||
#### P0-3b:服务层骨架(03_CoreModule §11-13)
|
||
- [x] `ServiceLocator` 静态类(`Register<T>` / `Get<T>` / `GetOrDefault<T>` / `OverrideForTest<T>` / `Reset`)
|
||
- [x] `GameServiceRegistrar`(ExecutionOrder -2000,DontDestroyOnLoad;`Awake` 中注册所有核心服务)
|
||
- [x] 五大服务接口:`IAudioService`、`ISaveService`、`ISceneService`、`IDeathRespawnService`、`IEventChannelRegistry`
|
||
- [x] `NullAudioService`(空实现,测试/Editor 下兜底,不报错)
|
||
- [x] `DeathRespawnService`(实现 `IDeathRespawnService`,UniTask-based,封装死亡/重生序列;Phase 1 完成完整逻辑,Day 3 只建文件+接口)
|
||
- [x] `SceneService`(实现 `ISceneService`,UniTask-based,封装场景加载;Day 3 只建文件+接口)
|
||
|
||
#### P0-4:资产加载骨架(13_AssetPoolModule)
|
||
- [x] `AddressKeys` 静态常量类(填入当前已知地址;后续持续追加)
|
||
- [x] `AssetLoader` 工具类(封装 `Addressables.LoadAssetAsync`)
|
||
- [x] `AssetReleaseTracker`(场景卸载时批量 Release)
|
||
- [x] `AddressKeyRegistry`(运行时 key 注册层,DLC 扩展用;`TryRegister(key, addr)` / `Resolve(key)` / `TryResolve()` / `Unregister()` / `ForceRegister()`;`Core/Assets/AddressKeyRegistry.cs`;架构 13 §9)
|
||
- [x] Editor 工具:`AddressKeyValidator`(反射扫描 `AddressKeys` 所有常量,对比 Addressable 分组)+ `AddressKeyImportWatcher`(`AssetPostprocessor`,Addressable 分组变更后自动触发;`Editor/AddressKeyValidator.cs`;架构 13 §10)
|
||
|
||
#### P0-5:存档骨架(12_SaveModule 部分)
|
||
- [x] `SaveData` C# 完整数据结构(所有子类:`SaveMeta`、`PlayerSaveData`、`WorldSaveData` 等)
|
||
- [x] `ISaveStorage` 接口 + `LocalFileStorage` 实现(⚠️ 类名无 "Save" 前缀,架构 12 §2)
|
||
- [x] `SaveManager`(接口签名,`Save`/`Load`/`NewGame` 占位实现)
|
||
|
||
### Phase 0 完成标准
|
||
- Unity 编译无错,Console 无警告
|
||
- 能在 Editor 中运行 `Persistent` 场景(GameManager Awake 打印版本号)
|
||
- 能新建 / 加载 JSON 存档文件(即使数据为空)
|
||
- 所有 asmdef 引用方向通过 Assembly Reference Checker 验证
|
||
|
||
---
|
||
|
||
## 4. Phase 1:垂直切片 MVP
|
||
|
||
**目标**:一个完整可玩房间。验证所有第三方库集成点,建立可以往上叠加的可运行骨架。
|
||
|
||
**可玩标准**:玩家能在一个房间内移动、跳跃、普通攻击;有一只巡逻敌人能被击杀;房间内有存档点可存读档;死亡后从存档点复活。
|
||
|
||
### 任务清单
|
||
|
||
#### P1-1:输入系统(04_InputModule)
|
||
- [x] `InputReaderSO`(持有 `PlayerInputActions` 引用,暴露 Unity Events)
|
||
- [x] `InputBuffer`(三路独立缓冲:`_jumpBufferDuration = 0.15f`、`_attackBufferDuration = 0.12f`、`_dashBufferDuration = 0.10f`)
|
||
- [x] 配置 `PlayerInputActions.inputactions`(Gameplay / UI / Cutscene 三套 Action Map;存于 `Assets/Settings/PlayerInputActions.inputactions`)
|
||
- [x] 在 `Persistent` 场景挂载 `InputReader`
|
||
|
||
#### P1-2:相机系统(17_CameraModule)
|
||
- [x] `CameraStateController`(管理 GlobalCam / RoomCam 优先级)
|
||
- [x] `RoomVisibleArea`(每个房间场景的 `CinemachineConfiner2D` 边界)
|
||
- [x] `CameraTriggerZone`(触发切换活跃相机)
|
||
- [x] `CameraConfigSO`(Pixel Perfect 参数)
|
||
- [x] `CameraBlendProfileSO`(混合曲线配置 SO,`ToBlendDefinition()` 返回 Cinemachine v3 结构体)
|
||
- [x] `RoomCamera`(单房间 VCam 封装,`Activate()`/`Deactivate()` 优先级切换)
|
||
- [x] 配置 Cinemachine Virtual Camera + Pixel Perfect Camera 组合(Unity Editor 场景组装)
|
||
- [x] **验证点**:进入房间后相机锁定在正确边界,像素对齐无抖动
|
||
|
||
#### P1-3:玩家模块——基础(05_PlayerModule)
|
||
目标:Run/Jump/Fall/Idle/Attack 五个状态可运行
|
||
|
||
- [x] `PlayerController`(协调器字段 + Awake 注册 + Update 状态转发)
|
||
- [x] `PlayerMovement`(Rigidbody2D 移动,走/跳/落地)
|
||
- [x] `PlayerStats`(HP 字段,`TakeDamage` 接口)
|
||
- [x] `PlayerCombat`(基础近战攻击触发,HitBox 激活/停用)
|
||
- [x] `PlayerStateBase`(抽象基类;`PlayerStateMachine` 逻辑内嵌于 `PlayerController`)
|
||
- [x] State 实现:`IdleState`、`RunState`、`JumpState`、`FallState`、`AttackState`(✅)
|
||
- [x] `PlayerAnimationConfigSO` + `PlayerMovementConfigSO`(基础数值)
|
||
- [x] `PlayerStatsSO`(HP/灵力/弹簧/Geo 初始数值 SO)
|
||
- [x] **Animancer 集成验证点**:FSM 切换时 Animancer Linear 混合正常,无动画卡顿
|
||
|
||
#### P1-4:战斗管道(06_CombatModule)
|
||
- [x] `DamageInfo` struct + `Builder`
|
||
- [x] 所有枚举(`DamageType`、`DamageCategory`、`DamageFlags`、`DamageTags`、`HitFxType`、`BreakLevel`、`PoiseLevel`;⚠️ `DamageTags` 为 `[Flags]` 枚举含 15 个标记位,`PoiseLevel` 均定义于架构 06_CombatModule §2)
|
||
- [x] `DamageSourceSO`
|
||
- [x] `HitBox`(`OnTriggerEnter2D` → 收集重叠的 `HurtBox`,调用 `ReceiveDamage`)
|
||
- [x] `HurtBox`(`ReceiveDamage` 管道:防御计算 → `IDamageable.TakeDamage`)
|
||
- [x] `IDamageable` 接口
|
||
- [x] **伤害管道验证点**:玩家攻击命中敌人 HurtBox → 敌人 HP 减少,Console 打印 DamageInfo 内容
|
||
|
||
#### P1-5:基础敌人(07_EnemyModule)
|
||
目标:一只能巡逻、追玩家、被攻击、死亡的基础敌人
|
||
|
||
- [x] `EnemyBase`(`IDamageable`,`TakeDamage`/`Die`)
|
||
- [x] `EnemyStats` + `EnemyStatsSO`(基础 HP/攻击力)
|
||
- [x] `EnemyMovement`(Rigidbody2D,配合 NavAgent)
|
||
- [x] `EnemyNavAgent`(封装 PathBerserker2d `NavAgentComponent`)
|
||
- [x] `EnemyCombat`(近战攻击区域,触发玩家 HurtBox)
|
||
- [x] NavSurface 烘焙(测试房间地形)
|
||
- [x] Behavior Designer 任务类:`BD_Patrol`、`BD_MoveToPlayer`、`BD_Attack`、`BD_IsPlayerInRange`(⚠️ 类名以架构 07_EnemyModule §8 为准,非 BD_ChasePlayer/BD_AttackPlayer/BD_CheckPlayerDistance)
|
||
- [x] 一份基础 BehaviorTree 资产(Patrol → Detect → Chase → Attack)
|
||
- [x] **PathBerserker2d + Behavior Designer 集成验证点**:敌人能在 NavSurface 上寻路追玩家
|
||
|
||
#### P1-6:存档完整实现(12_SaveModule)
|
||
- [x] `SaveManager` 完整实现(`Save`、`Load`、`NewGame`、`DeleteSave`)
|
||
- [x] `SavePoint` 场景组件(触发存档,广播 `_onSavePointActivated`)
|
||
- [x] `ISaveable` 接口 + `PlayerSaveData` 读写(HP、位置、当前场景)
|
||
- [x] `SaveMigrator`(版本号检查)
|
||
- [x] `EmergencySaveService`(定时自动存档)
|
||
- [x] **存档验证点**:Play → 激活存档点 → 退出 Play → 再 Play → 正确加载到存档位置
|
||
|
||
#### P1-7:最简 UI(10_UIModule)
|
||
- [x] `UIManager`(Panel 层级管理,`OpenPanel`/`CloseTopPanel`;⚠️ 非 `ShowPanel`/`HidePanel`,架构 10 §2)
|
||
- [x] `HUDController`(HP 条 + 当前货币;⚠️ 非 `HUDPanel`,架构 10 §3)
|
||
- [x] 订阅 `_onHPChanged`、`_onGeoChanged` 事件频道更新 HUD(⚠️ 货币频道名为 `_onGeoChanged`,架构 10 §3)
|
||
- [x] `DeathScreenController`(占位,显示"You Died";⚠️ 非 `DeathPanel`,架构 10 §6)
|
||
|
||
#### P1-8:最简音频钩子(11_AudioModule)
|
||
- [x] `AudioManager`(单例,`PlaySFX`/`PlayBGM` 接口)
|
||
- [x] `AudioMixerKeys`(Exposed Parameter 常量类)+ `AudioConfigSO`(区域 BGM 映射)
|
||
- [x] `BGMController`(订阅 Zone/Boss 事件驱动 BGM 切换)+ `AudioZone`(区域切换触发)
|
||
- [x] 在伤害管道和死亡事件上挂上 SFX 钩子(`CombatSFXController` 订阅 `HitConfirmedEventChannelSO` + `_onPlayerDied`)
|
||
|
||
#### P1-9:VFX 最简(18_VFXFeedbackModule 骨架)
|
||
- [x] `VFXPool`(基于 `GlobalObjectPool` 的 VFX 专用包装)
|
||
- [x] `HitFXSpawner`(根据 `DamageInfo.FxType` 路由到 VFX Prefab)
|
||
- [x] `HurtFlashController`(白闪 Shader 参数控制)
|
||
- [x] `VFXCatalogSO`(填入2-3个占位 Prefab)
|
||
- [x] **验证点**:击中敌人时播放命中特效和白闪
|
||
|
||
#### P1-10:死亡复活流程串联(03_CoreModule §8)
|
||
- [x] `GameManager` 完整实现死亡/复活时序
|
||
- [x] 接通事件链:`_onPlayerDied` → `GameManager.OnPlayerDied()` → `DeathScreenController` → 等待输入 → `SceneLoader.ReloadFromSave()`
|
||
|
||
### Phase 1 完成标准
|
||
| 验证项 | 要求 |
|
||
|--------|------|
|
||
| 玩家可移动/跳跃/攻击 | Animancer FSM 无卡顿 |
|
||
| 敌人能寻路追击攻击 | PathBerserker2d + Behavior Designer 无报错 |
|
||
| 攻击命中有 VFX 和音效 | 事件链完整 |
|
||
| 激活存档点,退出重进,正确复位 | SaveManager JSON 读写正确 |
|
||
| 玩家死亡 → 死亡画面 → 复活 | GameManager 状态机流转正确 |
|
||
| 相机锁定房间,像素对齐 | 无亚像素抖动 |
|
||
| Console 无错误,无 MissingReference | — |
|
||
|
||
---
|
||
|
||
## 5. Phase 2:核心玩法扩展
|
||
|
||
**目标**:在 Phase 1 的可运行骨架上,填充完整的玩家能力、战斗纵深、多种敌人。
|
||
|
||
### 任务清单
|
||
|
||
#### P2-1:玩家完整 FSM(05_PlayerModule 剩余)
|
||
- [x] State 补充(Week 5):`DashState`、`AerialDashState`、`WallSlideState`、`WallJumpState`、`AirAttackState`、`DownAttackState`、`UpAttackState`、`HurtState`、`DeadState`、`SpringState`、`ParryState`
|
||
- [x] `SwimState`(`21_LiquidPuzzleModule §SwimState`,✅ Week 11 完成)
|
||
- [x] `PlayerWallDetector`(独立墙壁检测组件,双射线每侧防误判)
|
||
- [x] `PlayerMovementConfigSO` 补充 `DefaultGravityScale`
|
||
- [x] `FormController`(三形态切换:Sky/Earth/Death;含 `FormType`、`FormSO`、`FormConfigSO`)
|
||
- [x] `WeaponManager`(FormController 联动 + Override 护符替换 API;含 `WeaponSO` 完整字段扩展)
|
||
- [x] `PlayerCombat` 完整实现(HitBox 四向激活、`SetComboSegmentSource`、`OnHitConfirmed`→灵力)
|
||
- [x] `PlayerController` Phase 2 扩展(`IPoiseSource` + 11 个新状态 + `TakeDamage` 路由到 HurtState/DeadState)
|
||
- [x] `SkillManager`(技能槽 + 冷却计时)— 已在 P3-3 完整实现(`BaseGames.Skills` 程序集)
|
||
- [x] `SpringSystem`(头部弹簧摆动,完整实现)
|
||
- [x] Animancer 双层动画:Base Layer(移动动画)+ Overlay Layer(叠加层:灵泉/魂技能)✅ 2026-05-12(`PlayerController` 初始化 Layer 1;`PlayOnOverlay`/`StopOverlay` API;`SpringState` 改用叠加层)
|
||
|
||
#### P2-2:护盾系统(20_ShieldModule)
|
||
- [x] `ShieldComponent`(Phase 2 完整实现:护盾值吸收、再生延迟、破盾惩罚事件;新增 `FullRecharge()` / `OnParrySuccess()` / 破碎惩罚计时;可选 `ShieldConfigSO` 覆盖内联字段)
|
||
- [x] `ShieldConfigSO`(MaxShieldHP、DamageAbsorptionRatio、RechargeDelay、RechargeRate、BrokenPenaltyDuration、ParryRestoreRatio)
|
||
- [x] `IShieldable` 接口(`CombatInterfaces.cs`)
|
||
- [x] `HurtBox.ReceiveDamage` 接入护盾管道(步骤 4 `AbsorbDamage` 已实现,ConsumeParry 步骤 2 已实现)
|
||
- [x] 护盾破碎/恢复 VFX 钩子 ✅ 2026-05-13(`ShieldComponent` 新增 `_onShieldBrokenChannel` / `_onShieldRestoredChannel` VoidEventChannelSO 字段,破碎时 Raise,破碎惩罚结束及 FullRecharge 时 Raise restore)
|
||
|
||
#### P2-3:完整战斗系统(06_CombatModule 剩余)
|
||
- [x] `ProjectileConfigSO` + `LinearProjectile` + `ParryableProjectile`(+ `ArcProjectile`、`HomingProjectile`、`ProjectileManager`)
|
||
- [x] `ParrySystem` 5 阶段状态机(Inactive/Startup/Active/EndLag/CounterWindow)+ 完美弹反子弹时间 + C# 事件 + `ParryConfigSO`(全部 12 个字段)
|
||
- [x] `ParryInfo` struct + `ParryInfoEventChannelSO`(SO 事件频道,`BaseGames.Parry` 程序集)
|
||
- [x] `PoiseWindowConfig` struct(`[Serializable]`,描述动画时间段霸体等级)+ `EnemyPoiseComponent`(`IPoiseSource` 实现,自动注入 HurtBox)
|
||
- [x] `StatusEffectManager` + `StatusEffect`(抽象基类,架构 06_CombatModule §11,非 `StatusEffectBase`)+ 具体效果(Poison、Burn、Freeze、Stun)→ **已在 P2-4b 实现**
|
||
- [x] `IBreakable`(机关/障碍物交互接口;`CombatInterfaces.cs` 内定义;`HitBox` 已在命中非 `HurtBox` 时尝试调用)
|
||
- [x] `ClashResolver`(拼刀系统:同帧玩家/敌人 HitBox 对碰检测,广播 `EVT_NailClash`;架构 06 §15)✅ 2026-05-11(`ClashConfigSO.cs`、`ClashResolver.cs` 新建;`HitBox.cs` 加入拼刀检测分支,`CanClash` / `IsActive` / `OwnerRigidbody` 属性)
|
||
|
||
#### P2-4:动画事件系统(24_AnimEventModule)✅ Week 7(2026-05-11)
|
||
- [x] `AnimationEventType` enum(21 种事件类型)
|
||
- [x] `AnimationEventConfigSO`
|
||
- [x] `AnimationEventBinder`
|
||
- [x] `PlayerAnimationEvents`(挂在玩家上)
|
||
- [x] `EnemyAnimationEvents`(挂在敌人上)
|
||
- [x] `IAnimationEventHandler` 接口(⚠️ 非 `IAnimEventReceiver`,架构 24_AnimEventModule §1 patch)
|
||
- [x] 将 AttackState HitBox 激活时机从 FixedUpdate 改为 AnimEvent 驱动(已通过 Animancer `events.Add(0.3f/0.6f, ...)` 归一化时间事件实现)
|
||
- [x] Editor 工具:`EventConfigEditor`(`[CustomEditor(typeof(AnimationEventConfigSO))]`;时间轴标记点可视化、Clip 漂移检测(偏差>5帧警告)、normalizedTime 越界保护、事件类型着色;架构 24 §10)
|
||
|
||
#### P2-4b:状态效果系统(06_CombatModule §11)✅ Week 7(2026-05-11)
|
||
- [x] `StatusEffectType.cs` 枚举(Fire/Poison/Stagger/Freeze/Stun;⚠️ 架构定义 4 个值 Fire/Poison/Freeze/Stun,Stagger 为实现扩展)
|
||
- [x] `StatusEffect.cs` 抽象基类(双计时器:Duration + TickTimer;OnApply/OnStack/OnTick/OnExpire)
|
||
- [x] `FireEffect.cs`(DoT,MaxStacks=1,**3s**/0.5s/**1dmg True**/tick;OnApply/OnExpire 设置 `_FireGlow` Shader 参数)
|
||
- [x] `PoisonEffect.cs`(DoT,MaxStacks=3,**5s**/1s/**StackCount dmg True**/tick;OnApply/OnStack/OnExpire 管理 `_PoisonGlow` Shader 参数)
|
||
- [x] `StaggerEffect.cs`(硬直,MaxStacks=1,可自定义持续时间;架构扩展,非核心规格)
|
||
- [x] `StatusEffectEventChannelSO.cs`(SO 事件频道,携带 StatusEffectEvent struct;架构用 StatusEffectType 直接广播,实现扩展为含 StackCount/RemainingDuration 的 struct 更利 UI)
|
||
- [x] `StatusEffectManager.cs` 完整实现(List + Dictionary 双结构;ApplyEffect/CleanseEffect/CleanseAll/HasEffect;`ApplyDirectDamage(DamageInfo)` 替代旧 DealDotDamage;`SetShaderParam(string,float)` via MaterialPropertyBlock;SpriteRenderer 初始化于 Awake)
|
||
|
||
#### P2-5:完整 VFX 反馈(18_VFXFeedbackModule 完整)
|
||
- [x] `FeedbackConfigSO`(`HurtFlashColor`/`HurtFlashDuration`;Phase 2 扩充 Feel 封装字段)
|
||
- [x] `IFeedbackPlayer` 接口(完整 API:PlayHit/PlayTakeHit/PlayDeath/PlayHeal/PlayLandImpact 等)+ `PlayerFeedback`、`EnemyFeedback`、`NullFeedbackPlayer` 实现
|
||
- [ ] `VFXCatalogSO` 填入全部 VFX Prefab(命中/死亡/技能/环境)
|
||
- [x] 接通 Feel MMF_Player 到相机震动、控制器震动 ✅ 2026-05-13(新增 `PostProcessManager`、`RegionLightController` + `RegionLightCatalogSO`、`PaletteSwapSystem` + `PaletteCatalogSO`;`BaseGames.VFX.asmdef` 加入 `BaseGames.Player` 引用)
|
||
|
||
#### P2-6:难度系统(19_DifficultyModule)✅ Week 8(2026-05-10)
|
||
- [x] `DifficultyLevel` enum(已在 Core.Events,`Easy/Normal/Hard/SteelSoul`)
|
||
- [x] `DifficultyScalerSO` × 4 份资产(Easy/Normal/Hard/SteelSoul — 脚本已创,Unity 内创建资产)
|
||
- [x] `DifficultyManager`(`DefaultExecutionOrder: -900`,SteelSoul 不可降级)
|
||
- [x] `BoolEventChannelSO`(新增,BossBase 依赖)
|
||
- [x] `PlayerStats` 订阅 `DifficultyChangedEventChannel`,难度切换时按 HP 比例缩放(`hpRatio × newMax`)并广播 `_onHPChanged`/`_onMaxHPChanged` ✅ 2026-05-11
|
||
- [x] `EnemyStats` 订阅 `DifficultyChangedEventChannel` 支持运行时切换;`Initialize()` 只缩放 HP,不缩放 Defense(架构 19 §5);提取 `ApplyHPScaler()` ✅ 2026-05-11
|
||
- [x] `ShopController.GetEffectivePrice()` 新增公开方法;`TryPurchase()` 改用实际价格(含 `ShopPriceMultiplier`)✅ 2026-05-11
|
||
- [x] `DeathRespawnService.StartGameOverCoroutine()` 实现:删除存档槽 → `ISceneService.LoadMainMenuCoroutine()` ✅ 2026-05-11
|
||
- [x] `SaveManager.CurrentSlot` 公开属性(供 DeathRespawnService 获取当前槽)✅ 2026-05-11
|
||
- [x] `GameManager.DeathFlow()` 接入 SteelSoul 分支:检查 `InstantDeathOnZeroHP`,true 时调用 `StartGameOverCoroutine()` 跳过普通死亡流程 ✅ 2026-05-11
|
||
- [x] `DifficultyScalerSO` × 4 份资产(Easy/Normal/Hard/SteelSoul — 脚本已创,Unity 内创建资产)
|
||
- [x] 钢铁之魂模式:`SaveMeta.IsSteelSoul` 字段写入 + `DifficultyManager` 实现 `ISaveable`(OnSave/OnLoad)在读档时锁定难度 ✅ 2026-05-11
|
||
|
||
#### P2-7:敌人扩展(07_EnemyModule 剩余)✅ Week 9(2026-05-10)
|
||
- [x] `BossBase`(Phase 切换 EnterPhase/IsHPBelow/Die 广播)
|
||
- [x] `ProjectileConfigSO` + `Projectile` (Linear/Arc/Homing/Parryable) + `ProjectileManager`
|
||
- [x] `RangedEnemy` + `FlyingEnemy`(EnemyBase 子类)
|
||
- [x] `DeathShade`(IInteractable,Geo 回收事件)
|
||
- [x] `LootTableSO` + `LootResolver`(加权随机掉落 + 难度缩放;`SpawnGeo`/`SpawnItem` 调用 `CollectibleSpawner` 静态方法,Phase 3 TODO 占位已移除)✅ 2026-05-11
|
||
- [x] `AttackPatternSO` + `TelegraphSystem` ✅ 2026-05-12
|
||
- [x] `EnemyQuotaManager` ✅ 2026-05-12
|
||
- [x] `BatchLOSSystem` + `ILOSRequester` ✅ 2026-05-12
|
||
- [x] `BD_` 任务类补充(14 个 Action + Conditional)✅ 2026-05-12
|
||
|
||
#### P2-8:音频系统完整(11_AudioModule 完整)✅ Week 8(2026-05-10)
|
||
- [x] `AudioEventSO`(随机音效 SO,Play / PlayOneShot)
|
||
- [x] `GlobalSFXPlayer`(静态 SFX 入口,2D + 世界坐标 3D 播放)
|
||
- [x] 为所有模块 SFX 钩子连接 `AudioEventSO` ✅ 2026-05-13(`CombatSFXController` 全部字段由 `AudioClip` 升级为 `AudioEventSO`,通过 `GlobalSFXPlayer.Play()` 播放,支持随机音量/音调/多片段)
|
||
|
||
---
|
||
|
||
## 6. Phase 3:世界与进程系统
|
||
|
||
**目标**:完整地图探索、谜题机关、任务系统、商店;存档数据完整;关卡编辑器工具就绪。
|
||
|
||
### 任务清单
|
||
|
||
#### P3-1:世界模块完整(08_WorldModule)✅ Week 10 代码完成
|
||
- [x] `RoomTransition`(门/传送,Additive 场景加载/卸载)
|
||
- [x] `HazardZone`(即死/持续伤害区域)
|
||
- [x] `Collectible`(Geo/物品,弧线吸附)
|
||
- [x] `DestructibleTile`(三帧图集,三种触发条件)+ `DirectionalDestructible`
|
||
- [x] `DirectionalInteractable`(OneShot 持久化)
|
||
- [x] `MovingPlatform`(三种 MoveType + 乘客 Parent 方案)
|
||
- [x] `CrumblePlatform`(四态状态机 + NavLink 联动)
|
||
- [x] `FalseWall`(三种揭示条件)
|
||
- [x] `MagicWall`(仅 Gizmo,Layer Matrix 实现)
|
||
- [x] `SoftTerrain`(Marker 组件)
|
||
- [x] `PhantomInteractable`(继承 `DirectionalInteractable`,响应 `PhantomBody` 层)
|
||
- [x] `WorldStateRegistry`(运行时缓存已触发/已破坏状态)
|
||
- [x] `CollectibleSpawner`(静态生成器;`SpawnGeo(Vector2, int)` / `SpawnItem(Vector2, string)`;由 `LootResolver` 调用)+ `CollectibleSpawnerConfig`(MonoBehaviour,Persistent 场景持有 GeoPrefab/ItemPrefab 引用,Awake 注册到 CollectibleSpawner)✅ 2026-05-11
|
||
- [x] `Collectible.SetGeo(int)` / `SetItem(string)`(运行时配置方法,由 CollectibleSpawner 实例化后调用;移除旧静态 SpawnGeo Debug.Log 占位)✅ 2026-05-11
|
||
- [x] `RoomTransition.HasItem` 接入 `WorldStateRegistry.IsCollected(itemId)`(不再返回硬编码 true;新增 `[SerializeField] private WorldStateRegistry _worldState` 字段)✅ 2026-05-11
|
||
- [ ] 场景内端对端验证(Unity 编辑器内 Prefab 装配 + 运行验证)
|
||
|
||
#### P3-2:液体与谜题系统(21_LiquidPuzzleModule)✅ Week 11 代码完成
|
||
- [x] `LiquidZone` + `LiquidType` enum
|
||
- [x] `LiquidPhysicsConfigSO`(浮力、水下速度)
|
||
- [x] `SwimState`(已在 P3-2 完成)
|
||
- [x] `ISwitchable`、`IActivatable` 接口
|
||
- [x] `PuzzleSwitch`、`PuzzleReceiver`(AND/OR/XOR 逻辑)、`PuzzleWire`(可视化连接)
|
||
- [x] `WaterDangerState` + `UnderwaterPostProcessingController`(架构 21 §12-13)
|
||
- [x] `FootstepMaterial` + `FootstepAudioConfigSO` + `UnderwaterAudioController`(架构 21 §3.3-3.4)
|
||
- [x] `WorldMarker` + `BreadcrumbTracker` ✅ 2026-05-12
|
||
- [x] `TutorialManager` + `ContextualHintTrigger` ✅ 2026-05-12
|
||
|
||
#### P3-3:进度系统(09_ProgressionModule)✅ 完成(2026-05-10)
|
||
- [x] `AbilityGate`(能力锁区域,检查 `PlayerStats.HasAbility()`)
|
||
- [x] `AbilityUnlock`(解锁 Prefab,播放解锁演出)
|
||
- [x] `CharmSO`、`EquipmentManager`(护符装备/卸载,Notch 管理)
|
||
- [x] `CharmCatalogSO`(护符目录 SO,`Find(charmId)→CharmSO`;`EquipmentManager.AddToCollection` + `OnLoad` 依赖)✅ 2026-05-11
|
||
- [x] `EquipmentManager.AddToCollection` 完整实现(从 CharmCatalogSO 查找 → 去重加入 `_collected`;旧 Debug.Log 占位已移除)✅ 2026-05-11
|
||
- [x] `EquipmentManager.OnSave/OnLoad` 完整实现(读写 `OwnedCharmIds`;OnLoad 恢复 `_collected` 后逐个调用 `TryEquipCharm`)✅ 2026-05-11
|
||
- [x] `FormSkillSO`、`SkillManager`、`SkillModifierRegistry`(技能数据+管理+修改器)
|
||
- [x] `ToolSO`、`ToolSlotManager`(两槽工具 + 冷却)+ `ToolHUD`
|
||
- [x] `ToolCatalogSO`(工具目录 SO,`Find(toolId)→ToolSO`;`ToolSlotManager.OnLoad` 依赖)✅ 2026-05-11
|
||
- [x] `ToolSlotManager.OnLoad` 完整实现(从 ToolCatalogSO 查找两槽 toolId → 调用 `EquipTool(i, tool)`;旧 TODO 已移除)✅ 2026-05-11
|
||
- [x] `EquipmentManager`(护符装备,多态 ICharmEffect)
|
||
- [x] `RegionDefinitionSO`、`ProgressLock`、`BossProgressTracker`、`HPContainerPickup`
|
||
- [x] `SkillHitBoxInstance`(技能 HitBox Prefab 组件)
|
||
- [x] `CharmEffectDrawer`(Editor 护符效果下拉 Inspector)
|
||
|
||
#### P3-4:任务与挑战(22_QuestChallengeModule)✅ 完成(2026-05-11)
|
||
- [x] `QuestSO`、`QuestObjectiveSO`(5 种具体类型)、`RewardSO`(物品发放通过 `StringEventChannelSO _onItemGranted.Raise(id)` 广播,旧 InventoryManager 占位已移除)✅ 2026-05-11
|
||
- [x] `QuestManager`(ISaveable,事件驱动进度追踪)
|
||
- [x] `QuestGiver`(继承 InteractableNPC,根据任务状态切换对话)
|
||
- [x] `InteractableNPC`、`DialogueSequenceSO`(BaseGames.Dialogue 基础实现)
|
||
- [x] `ChallengeRoomSO`、`ChallengeEncounterSO`、`BossRushSequenceSO`
|
||
- [x] `ChallengeRoomManager`(Addressables 波次生成,快存/快读)
|
||
- [x] `ChallengeRoomTrigger`(IInteractable 入口,事件触发场景加载)
|
||
- [x] `EnemyBase` 扩展:`EnemyId` 属性 + `OnDied` 事件
|
||
|
||
#### P3-5:地图与商店(15_MapShopModule)✅ 完成(2026-05-11)
|
||
- [x] `MapRoomDataSO` + `MapDatabaseSO` + `RoomExitData` + `ExitDirection`(房间数据 SO;架构 15 §1.1)
|
||
- [x] `MapManager`(ISaveable;订阅 `EVT_RoomEntered`;`SetMapped(roomId)`;`[DefaultExecutionOrder(-700)]`;架构 15 §1.2)
|
||
- [x] `MapPanel` + `MapRoomCellUI`(格子地图 UI;订阅 `EVT_MapUpdated` 增量刷新;架构 15 §1.3)
|
||
- [x] `MapPlayerTracker`(`WorldToCell` 换算;LateUpdate 找所在房间;架构 15 §1.4)
|
||
- [x] `MapPinManager`(ISaveable;`_pins: List<MapPin>`;MapPin/PinType 定义在 SaveData.cs 避免循环依赖;架构 15 §1.5)
|
||
- [x] `ShopItemSO` + `ShopItemType`(架构 15 §2.1)
|
||
- [x] `ShopInventorySO` + `RestockPolicy`(架构 15 §2.2)
|
||
- [x] `ShopController`(ISaveable;`TryPurchase`;`GetAvailableItems`;`Restock`;`ShopPanel` 存根;架构 15 §2.3)
|
||
- [x] `ShopNPC`(IInteractable;`DialogueEventChannelSO` 触发招呼对话→打开商店;架构 15 §2.4)
|
||
- [x] Editor 工具:`MapRoomDataEditor`(`[CustomEditor(typeof(MapRoomDataSO))]`;Scene 句柄拖拽 GridPosition/GridSize;"居中 Scene View"按钮;架构 15 §5)
|
||
|
||
#### P3-6:存档完善(12_SaveModule 剩余)✅ 2026-05-11
|
||
- [x] `CrashReporter` + `EmergencySaveService.PromoteToSlot` 完整实现(定时检点 + 崩溃日志)
|
||
- [x] `SaveMigrator` 版本迁移策略(v1.0→v1.1→v2.0→v2.1 字段兼容)
|
||
- [x] 存档槽 UI(`SaveSlotController` + `SaveSlotUI`;新建/删除/选择存档)
|
||
- [x] `SaveManager.DeleteSlotAsync` + `BaseGames.UI.asmdef` 添加 `BaseGames.Core.Save` 引用
|
||
|
||
---
|
||
|
||
## 7. Phase 4:内容与完善
|
||
|
||
**目标**:Boss 战系统、叙事/过场、平台服务层、本地化、Debug 工具,进入 QA 可测试状态。
|
||
|
||
### 任务清单
|
||
|
||
#### P4-1:Boss 技能系统(23_BossSkillModule)✅ 2026-05-11
|
||
- [x] `BossSkillTypes.cs`:全部枚举(`BossSkillCategory`、`BossSkillType`、`InteractionTag`、`VulnTriggerType`、`WeakPointType`、`CounterType`、`ArenaEventType`)及 Serializable struct(`VulnerabilityWindow`、`PlayerCounterResponse`、`ArenaEventTrigger`、`ArenaEventParams`、`ArenaEventData`、`BossResourceCost`、`IArenaInteractable`)
|
||
- [x] `BossSkillSO`(`CreateAssetMenu`,引用 `AttackPatternSO[]`、`VulnerabilityWindow[]`、`PlayerCounterResponse[]`、`ArenaEventTrigger[]`、`BossResourceCost`、`PoiseWindowConfig`、`ClipTransition`)
|
||
- [x] `AttackPatternSO`(伤害/弹幕/AoE/时序参数;`DamageSourceSO` 引用)
|
||
- [x] `SkillSequenceSO`(`SequenceStep[]`,含重复逻辑 `RepeatIfPlayerInRange`)
|
||
- [x] `BossResourceConfigSO`(Boss 自身资源配置,如愤怒值)
|
||
- [x] `BossSkillExecutor`(Coroutine 实现;`ExecuteSkill()` / `InterruptCurrentSkill()`;VulnerabilityWindow 与攻击序列并行协程;注:架构规格为 UniTask,当前用 Coroutine 实现以匹配项目实际依赖)
|
||
- [x] `WeakPointSystem`(弱点 HurtBox 激活管理;`SetActive(bool, float, bool)`;`_onVulnerabilityWindowOpened` 广播)
|
||
|
||
#### P4-2:叙事系统(14_NarrativeModule)✅ 2026-05-11
|
||
- [x] `DialogueSequenceSO` 补全 `DialogueLine.portraitSprite` / `typewriterDelay` 字段 ✅ 2026-05-11
|
||
- [x] `DialogueUI`(打字机效果,StringBuilder 零分配;`ShowLine` / `SkipTyping` / `Hide`;`IsTyping` 状态属性)✅ 2026-05-11
|
||
- [x] `DialogueManager`(Coroutine 驱动打字序列;`StartDialogue(sequence, npcId)`;Action Map 切换;广播 `EVT_NpcDialogueCompleted`;注册到 ServiceLocator)✅ 2026-05-11
|
||
- [x] `InteractionPromptController`(交互提示 UI;键盘/手柄图标自动切换;挂在 IInteractable 子节点)✅ 2026-05-11
|
||
- [x] `NarrativeNPC`(扩展 InteractableNPC;`DialogueVersion[]` 条件对话版本;接入 `WorldStateRegistry`)✅ 2026-05-11
|
||
- [x] `InteractableNPC.PlayDialogue()` 接入 `ServiceLocator.GetOrDefault<DialogueManager>()` ✅ 2026-05-11
|
||
- [x] `EventChainSO` + 内置 7 个 `ChainCondition` + 10 个 `ChainAction`(全事件频道驱动,无跨程序集直接依赖;`BaseGames.EventChain` 新程序集)✅ 2026-05-11
|
||
- [x] `EventChainManager`(订阅 5 条 StringEventChannelSO 中继;EvaluateAll;存档集成;防重入)✅ 2026-05-11
|
||
- [x] `CutsceneSO`(`TimelineAsset`;`CutsceneBinding[]`;`CameraBlendProfileSO` 混合;`DialogueSequenceSO[]` 叠加层)✅ 2026-05-11
|
||
- [x] `CutsceneManager`(`PlayableDirector` 封装;`PlayById` 事件驱动;Action Map 切换;`EVT_CutsceneStarted/Ended`)✅ 2026-05-11
|
||
- [x] `CutsceneTrigger`(4 种模式:OnEnter/OnInteract/OnSceneLoad/OnEvent;实现 `IInteractable`;WorldStateRegistry 去重)✅ 2026-05-11
|
||
- [x] `SignalEmitterClip` + `SignalEmitterBehaviour`(Timeline → VoidEventChannelSO 零耦合桥接;支持循环重播)✅ 2026-05-11
|
||
|
||
#### P4-3:输入重绑定(04_InputModule §6)✅ 2026-05-11
|
||
- [x] `InputReaderSO` 补全重绑定 API:`StartRebinding()`(自动 Dispose op)、`SaveBindingOverrides()`、`LoadBindingOverrides()`、`ResetBindings()`、`GetAllActionMap()`、`FindAction()` ✅ 2026-05-11
|
||
- [x] `InputReaderBootstrap` 启动时调用 `LoadBindingOverrides()`(在 `EnableGameplayInput()` 前)✅ 2026-05-11
|
||
- [x] `ConflictDetector`(扫描 Gameplay Map 重复 effectivePath;返回冲突 Action 名称 HashSet)✅ 2026-05-11
|
||
- [x] `RebindActionRow`(单行:显示当前绑定 HumanReadable 路径;排他锁 SetInteractable;冲突红色高亮)✅ 2026-05-11
|
||
- [x] `RebindPanel`(统一协调排他重绑定流程;`OnResetAll`;完成后自动 `SaveBindingOverrides`)✅ 2026-05-11
|
||
- [x] `BaseGames.UI.asmdef` 补充 `BaseGames.Input` + `Unity.InputSystem` 引用 ✅ 2026-05-11
|
||
|
||
#### P4-4:UI 完整(10_UIModule 剩余)
|
||
- [x] `PauseMenuController`(设置/键位重绑定/退出;架构 10 §7.3)✅ 2026-05-11
|
||
- [x] `SettingsPanelController`(音量/画质/帧率/VSync 设置面板;架构 10 §7.4)✅ 2026-05-11
|
||
- [x] `BossHPBar`(Boss 血条 + 阶段标记;订阅 EVT_BossFightToggled/HPChanged;架构 10 §4)✅ 2026-05-11
|
||
- [x] `SaveIndicator`(右下角存档提示;订阅 EVT_SaveIndicatorVisible;架构 10 §7.6)✅ 2026-05-11
|
||
- [x] `LoadingOverlay`(全屏黑幕淡入淡出;订阅 EVT_LoadingOverlay;架构 10 §8)✅ 2026-05-11
|
||
- [x] `LoadingScreenManager`(进度条 + 提示文字 + 随机背景;架构 10 §7.7)✅ 2026-05-11
|
||
- [x] `FloatingDamageText` + `FloatingDamageSpawner`(对象池伤害飘字;订阅 EVT_DamageDealt;架构 10 §10)✅ 2026-05-11
|
||
- [x] `ToastNotification` + `ToastManager`(成就/能力 Toast 队列弹出;架构 10 §11)✅ 2026-05-11
|
||
- [x] `InputDeviceIconSetSO` + `InputDeviceIconSwitcher` + `InputIconImage`(键鼠/手柄图标切换;架构 10 §12)✅ 2026-05-11
|
||
- [x] `BaseGames.UI.asmdef` 补充 `BaseGames.Combat` 引用 ✅ 2026-05-11
|
||
- [x] `SaveSlotController` + `SaveSlotUI`(主菜单 3 槽存档卡片 UI;架构 10 §7.5)✅ 已在 P3-6 完成
|
||
|
||
#### P4-5:支撑模块(16_SupportingModules)✅ 已完成
|
||
- [x] `LocalizationManager` + `LanguageManagerSO`(`#if UNITY_LOCALIZATION` 守卫;fallback 返回 key;架构 16 §5)
|
||
- [x] `IPlatformService` ServiceLocator + `SteamPlatformService` + `NullPlatformService` + `PlatformBootstrap`(架构 16 §2)
|
||
- [x] `AchievementManager`(通过 `ServiceLocator.Get<IPlatformService>()` 接入平台成就;12 条件类;架构 16 §3)
|
||
- [x] `AnalyticsManager`(本地 JSON 日志;TrackBossKill/TrackDeath/TrackSessionStart/End;架构 16 §7)
|
||
- [x] `DebugCheatSystem`(`#if UNITY_EDITOR || DEVELOPMENT_BUILD`;heal/addgeo/godmode/unlock/killall/scene/revive;架构 16 §4)
|
||
- [x] `AntiSoftlockSystem` + `RoomEscapeInfoSO` + `HardAbilityGate`(卡关检测 + 自动解锁;架构 16 §6)
|
||
- [x] `SpeedrunTimer`(unscaledDeltaTime;ISaveable;架构 16 §8)
|
||
- [x] `AccessibilitySettingsSO` + `AccessibilityManager` + `ColorBlindFilter`(色盲矩阵 URP RenderFeature;架构 16 §6)
|
||
- [x] `BaseGames.Support.asmdef`(引用 Core/Events/Save/Input/Player/Enemies/Combat/World/Progression/Platform/TMP/URP)
|
||
|
||
#### P4-6:编辑器工具(09_EditorExtensions)✅ 2026-05-11
|
||
- [x] `AddressKeyValidator`(Build Pre-process hook;`AddressKeyValidatorBuildHook` 在 `AddressKeyValidator.cs` 补充;callbackOrder=0;架构 13 §10)✅ 2026-05-11
|
||
- [x] `AddressReferenceGraphWindow`(`BaseGames/Tools/Asset Reference Graph`;扫描所有 `.cs` 对 `AddressKeys.X` 的引用,标红孤儿 key,橙色标注不在 Addressables 的 key,一键导出 CSV;架构 13 §11)✅ 2026-05-11
|
||
- [x] `DirectionalDestructible`/`FalseWall`/`MovingPlatform`/`HazardZone`/`RoomTransition` Gizmo 已实现;`DestructibleTile` Gizmo(`DestructibleTileEditor.cs`)已补充;`PhantomPlate` 已创建 ✅ 2026-05-11
|
||
- [x] `NavSurfaceBakeShortcut`(`%#b` 快捷键;`BaseGames/Tools/Bake All NavSurfaces`;完成时 SetDirty + 打印用时;架构 PathBerserker2d)✅ 2026-05-11
|
||
- [x] `EventChannelEditor`(`VoidBaseEventChannelSO` RaiseInEditor 按钮;`BaseEventChannelSO<T>` 订阅者数量显示;Play Mode only;架构 02 §9)✅ 2026-05-11
|
||
- [x] `CharmEffectDrawer`(`CharmSO.effects` 自定义 PropertyDrawer;实现为 `CharmSOEditor`,含类型下拉+效果预览;架构 16 §4.1)✅ 已在 P3-3 完成
|
||
- [x] `SOValidationRunner` + `IValidatable` 接口(预构建 SO 数据验证;菜单 `Tools/Validate All SOs` + `IPreprocessBuildWithReport`;架构 16 §10)✅ 2026-05-11
|
||
- [x] `EventBusMonitorWindow`(Editor Only;运行时事件监控面板,显示订阅者数量;架构 02 §9)
|
||
- [x] `EventChainEditorWindow`(`BaseGames/Tools/Event Chain Viewer`;左侧链列表/右侧条件+动作表格;Play Mode 运行时着色绿/橙;`ChainCompletedCondition` 依赖链显示;执行日志最近 20 条;双击 PingObject;架构 14 §13)✅ 2026-05-11
|
||
- [x] `BossSkillSequenceWindow`(`BaseGames/Tools/Boss Skill Sequence Viewer`;`BossSkillSO`/`SkillSequenceSO` 甘特图时间轴;Windup黄/Active红/Recovery灰/Vuln绿/Delay暗灰;拖放加载;架构 23 §12)✅ 2026-05-11
|
||
- [x] `AchievementSOEditor`(`[CustomEditor(typeof(AchievementSO))]`;条件中文类型标签;内联展开 SO 字段;Ping/Delete 按钮;架构 16 §2.4)✅ 2026-05-11
|
||
- [x] `BaseGames.Editor.asmdef` 补充 `BaseGames.EventChain` 引用 ✅ 2026-05-11
|
||
|
||
---
|
||
|
||
## 8. 模块依赖顺序
|
||
|
||
```
|
||
BaseGames.Core.Events
|
||
└─► BaseGames.Core(GameManager、SceneLoader、ObjectPool)
|
||
└─► BaseGames.Core.Save(SaveManager)
|
||
└─► BaseGames.Input(InputReaderSO)
|
||
└─► BaseGames.Camera(CameraStateController)
|
||
└─► BaseGames.Combat(DamageInfo、HitBox、HurtBox)
|
||
└─► BaseGames.Player(PlayerController + FSM)
|
||
└─► BaseGames.Enemies(EnemyBase + AI)
|
||
└─► BaseGames.World(WorldInteractables、RoomTransition)
|
||
└─► BaseGames.Progression(AbilityGate、Charms、Quest)
|
||
└─► BaseGames.UI(全量 Panel)
|
||
└─► BaseGames.Audio(AudioMixer + AudioEventSO)
|
||
└─► BaseGames.Dialogue/Cutscene
|
||
```
|
||
|
||
**原则**:低层模块不引用高层。`Core.Events` 是唯一无依赖模块,所有其他模块均可安全引用。
|
||
|
||
---
|
||
|
||
## 9. 技术风险与缓解策略
|
||
|
||
| 风险 | 严重度 | 缓解方案 |
|
||
|------|--------|---------|
|
||
| Animancer + Behavior Designer 冲突(双方均用 Update 驱动) | 🔴 高 | Phase 1 最先验证;`AnimancerComponent.Playable.Speed` 控制暂停,不与 BD 冲突 |
|
||
| PathBerserker2d NavSurface 烘焙在移动平台上失效 | 🟠 中 | Phase 1 验证 `LocalNavSurface`;失效则退化到手动 NavLink |
|
||
| Addressables 场景 Additive Load 内存泄漏 | 🟠 中 | `AssetReleaseTracker` 在 `SceneUnloaded` 回调中强制 Release;Phase 1 末验证 |
|
||
| AudioEventSO 未完整填充导致 SFX 静音 | 🟡 低 | Phase 1 先用 `AudioManager.PlaySFX(AudioClip)` 直接传 Clip,Phase 2 完成 `AudioEventSO` 后统一替换引用 |
|
||
| SO 事件频道大量 `.asset` 资产管理混乱 | 🟡 低 | `Assets/Data/Events/` 严格按模块子文件夹分组;命名规范 `EVT_{Module}_{Event}` |
|
||
| 钢铁之魂模式存档不可降级误操作 | 🟡 低 | `SaveData.Meta.IsSteelSoul` 写入后 `DifficultyManager` 锁死选项,UI 二次确认 |
|