多轮审查和修复

This commit is contained in:
2026-05-12 15:34:08 +08:00
parent f55d2a57c3
commit ebbbb7332e
805 changed files with 838724 additions and 1905 deletions

View File

@@ -0,0 +1,160 @@
# 代码深度评审 DeepDive 2026 Q2
> 评审范围:`Assets/Scripts/` 416 个 .cs 文件DeepDive_2026.md 修复完成后的新一轮评审)
> 重点模块Audio、Camera、Dialogue、Quest、Progression、EventChain、UI、Tutorial、World全子系统、Support
> 评审标准以商业级成熟作品Hollow Knight、Celeste、Hades为参照基线
---
## 一、评审维度与总分
| 维度 | 满分 | 得分 | 说明 |
|------|------|------|------|
| 架构设计 (Architecture) | 25 | 21 | SO 事件总线 + ServiceLocator 整体优秀,但仍有混用 Instance/ServiceLocator |
| 性能 (Performance) | 25 | 20 | 批处理 / 对象池 / 环形缓冲区均到位3 处反射调用是负担 |
| 可扩展性 (Extensibility) | 20 | 17 | 谜题接口、EventChain、WorldStateRegistry 设计良好;对话变体未实装 |
| 编辑器友好 (Editor UX) | 15 | 13 | HurtBoxEditor / EventBusMonitorWindow 完善;极少数字段缺少 Tooltip |
| 使用便利性 (DX / API) | 15 | 12 | 核心 API 简洁namespace 缺失与 SaveManager.Instance 残留拉低得分 |
| **合计** | **100** | **83** | |
---
## 二、各维度详细评分与问题清单
### 2.1 架构设计 (21/25)
#### 优点
- **SO 事件频道体系**成熟,`BaseEventChannelSO<T>` + `EventSubscription(IDisposable)` + `CompositeDisposable.AddTo()` 完整闭环,各系统无直接依赖。
- **ServiceLocator** 统一服务注册,`GetOrDefault<T>` 优雅处理可选服务。
- **GameStateMachine** 显式白名单状态机避免非法转换DeepDive_2026 已完善。
- **25 个 asmdef** 严格单向依赖链Core → Player → Combat → … → World编译隔离优秀。
- **WorldStateRegistry** 作为 ScriptableObjectSO 注入代替全局单例,设计一流。
- **EventChainManager** 中继 C# 事件架构清晰Editor 专用静态事件零运行时开销。
#### 问题
| ID | 文件 | 描述 | 严重性 |
|----|------|------|--------|
| A-1 | `QuestManager.cs` | `OnEnable/OnDisable` 使用已废弃的 `SaveManager.Instance?.Register/Unregister` | 中 |
| A-2 | `ShopController.cs` | 同 A-1`SaveManager.Instance?.Register/Unregister` | 中 |
| A-3 | `EventChainManager.cs` | `Awake` 中使用 `SaveManager.Instance?.GetCompletedChains()` | 中 |
| A-4 | `TutorialManager.cs` | 使用原始 Singleton 模式(`public static Instance`),未注册 ServiceLocator | 低 |
| A-5 | `DialogueManager.cs` | `ResolveVariant()` 为存根,变体条件从未与 `WorldStateRegistry` 实际对接 | 低 |
---
### 2.2 性能 (20/25)
#### 优点
- `EventBusMonitor`:固定 256 条 `EventRecord[]` 环形缓冲区Editor 零 GC。
- `GlobalObjectPool``WarmupAsync` 预热,`IObjectPoolService` 接口注册,`ServiceLocator` 解耦。
- `BatchLOSSystem``HashSet + List` 双结构O(1) 查重 + 分帧限制 8 个请求。
- `EquipmentManager.UsedNotches`:缓存字段,完全消除 LINQ Sum。
- `AudioManager`6 路 SFX 轮转池避免高密度战斗音效互戳BGM 双 Source 交叉淡入淡出。
- `HomingProjectile`:方向向量用 `sqrMagnitude` 比较速度上限,无开方开销。
#### 问题
| ID | 文件 | 描述 | 严重性 |
|----|------|------|--------|
| P-1 | `LiquidZone.cs` | `PlayFeedback()` 通过 `GetMethod("PlayFeedbacks")` 反射调用,每次玩家进出液体区都触发 | 高 |
| P-2 | `PuzzleSwitch.cs` | 同 P-1同一反射模式 | 高 |
| P-3 | `PuzzleReceiver.cs` | 同 P-1同一反射模式 | 高 |
| P-4 | `Projectile.cs` | `ReturnToPool()` 使用 `GlobalObjectPool.Instance`(已标废弃),应走 ServiceLocator | 低 |
---
### 2.3 可扩展性 (17/20)
#### 优点
- `PuzzleInterfaces.cs``ISwitchable / IMovable / IActivatable` 三接口,谜题元素完全可替换实现。
- `AchievementCondition` + 11 个具体实现:抽象基类 + 工厂,新增成就类型零侵入现有代码。
- `EventChainSO` + `ChainCondition`ScriptableObject 配置驱动,策划可在 Inspector 搭建复杂叙事链。
- `WorldStateRegistry.WorldObjectCategory`:枚举泛化 API一个 registry 统一 Collectible/Door/Flag 等全部世界状态。
- `ToolSlotManager`:工具栏插槽与 SO 解耦,扩展新工具只需新建 ToolSO。
#### 问题
| ID | 文件 | 描述 | 严重性 |
|----|------|------|--------|
| E-1 | `DialogueManager.cs` | `ResolveVariant` 永远返回原始序列;条件分支对话完全无效 | 中 |
| E-2 | `AchievementManager.cs` | 注册为具体类型 `Register<AchievementManager>`,无法在测试中 mock | 低 |
---
### 2.4 编辑器友好 (13/15)
#### 优点
- `HurtBoxEditor`:运行时实时展示注入对象,调试受击逻辑极为便利。
- `EventBusMonitorWindow`:环形缓冲区在 Editor 窗口可视,零 GC。
- `BossSkillSequenceWindow`Boss 技能序列可视化 Inspector。
- `AddressKeyValidator`:构建时自动校验 Addressable Key 拼写,防止发布错误。
- `WorldStateRegistry.OnEnable() => _states.Clear()`:每次进入 Play Mode 自动重置 SO 状态,无脏数据问题。
- `EventChainManager``OnChainExecutedInEditor` 静态事件仅在编辑器存在,零运行时影响。
#### 问题
| ID | 文件 | 描述 | 严重性 |
|----|------|------|--------|
| UX-1 | 全局 | `SpeedrunTimer``AccessibilityManager` 缺少 namespaceIDE 浏览/搜索时易混淆 | 低 |
| UX-2 | `AntiSoftlockSystem.cs` | 类体未在 namespace 内缩进,与项目其他文件风格不一致 | 低 |
---
### 2.5 使用便利性API/DX(12/15)
#### 优点
- `ServiceLocator.GetOrDefault<T>(fallback)` 安全查询,代码调用方无需 null 判断。
- `DamageInfo.From(so, knockDir, sourcePos, layer)` 工厂方法 + `Builder`:两种构造路径清晰。
- `CompositeDisposable.AddTo()`Rx 风格订阅管理,防止事件泄漏。
- `QuestManager``IQuestManager` 接口 + `ServiceLocator.Register<IQuestManager>(this)`,调用方面向接口编程。
- `SkillSlotNames`:常量类消除 `"SoulSkill"` 等魔法字符串。
#### 问题
| ID | 文件 | 描述 | 严重性 |
|----|------|------|--------|
| D-1 | `SpeedrunTimer.cs` | 缺少 namespace与全局命名空间污染冲突 | 低 |
| D-2 | `AccessibilityManager.cs` | 缺少 namespace | 低 |
| D-3 | `UIManager.cs` | `TogglePause()` 只开不合,按两次暂停后第二次无效 | 中 |
| D-4 | `AchievementManager.cs` | `_saveRef` 字段在 `OnLoad` 赋值后从未读取(死代码) | 低 |
---
## 三、与商业标准的横向对比
| 对比项 | Hollow Knight 参照模式 | 本项目现状 |
|--------|------------------------|-----------|
| 事件解耦 | 自定义 C# 事件 + delegate | SO 频道体系,更 Inspector 友好 ✓ |
| 状态机 | 纯 C# 非 MonoBehaviour 状态 | 同PlayerStateBase 模式一致 ✓ |
| 对象池 | 静态池,键值 string | GlobalObjectPool + IObjectPoolService + ServiceLocator ✓✓ |
| 存档系统 | PlayerPrefs + 二进制 | Newtonsoft.Json + MD5 校验 + SemaphoreSlim 防并发 ✓✓ |
| 依赖注入 | 无(大量 singleton | ServiceLocator部分残留 singleton 待清理) ≈ |
| Addressables | Unity 自有 AssetBundle | Addressables + AddressKeyValidator 构建校验 ✓✓ |
| 谜题系统 | 基于碰撞的单一谜题 | ISwitchable/IActivatable 接口体系 ✓✓ |
| 对话变体 | 全局标记条件分支 | 框架存在但未接入 WorldStateRegistryTODO △ |
| 速通支持 | 无内置计时器 | SpeedrunTimer + ISaveable 持久化 ✓ |
| 无障碍 | 无内置色盲/震屏控制 | AccessibilityManager + ColorblindFilter ✓ |
---
## 四、修复项汇总(按优先级)
| 优先级 | ID | 文件 | 修复内容 |
|--------|----|------|----------|
| 高 | P-1,P-2,P-3 | `LiquidZone.cs`, `PuzzleSwitch.cs`, `PuzzleReceiver.cs` | 反射 → `MoreMountains.Feedbacks.MMFeedbacks` 直接转型 |
| 中 | A-1 | `QuestManager.cs` | `SaveManager.Instance``ServiceLocator.GetOrDefault<SaveManager>()` |
| 中 | A-2 | `ShopController.cs` | 同上 |
| 中 | A-3 | `EventChainManager.cs` | 同上 |
| 中 | D-3 | `UIManager.cs` | `TogglePause()` 改为真实 toggle |
| 低 | P-4 | `Projectile.cs` | `GlobalObjectPool.Instance``ServiceLocator.GetOrDefault<IObjectPoolService>()` |
| 低 | D-1 | `SpeedrunTimer.cs` | 补齐 namespace |
| 低 | D-2 | `AccessibilityManager.cs` | 补齐 namespace |
| 低 | D-4 | `AchievementManager.cs` | 删除 `_saveRef` 死代码字段 |
| 低 | UX-2 | `AntiSoftlockSystem.cs` | 类体补全缩进 |
---
## 五、不在本次修复范围内的已知问题(技术债)
| 问题 | 原因/说明 |
|------|----------|
| `DialogueManager.ResolveVariant()` 存根 | 需 Phase 4 完整接入 `WorldStateRegistry` 条件标记,属功能开发范畴,非代码质量问题 |
| `TutorialManager` raw singleton | 功能正确,仅可测试性不足;整改需新增接口,成本大于收益 |
| `AchievementManager` 注册具体类型 | 暂无 mock 需求,改为接口注册需新建 interface暂缓 |
| `AudioManager.PlayBGM/PlaySFX(key)` 存根 | 等待 Phase 2 AudioEventSO 模块,属功能开发范畴 |