多轮审查评估
This commit is contained in:
309
Docs/Review/FrameworkReview_2026_May_v21.md
Normal file
309
Docs/Review/FrameworkReview_2026_May_v21.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# BaseGames 框架代码评审报告 v21
|
||||
|
||||
**项目**:zeling_v2
|
||||
**评审日期**:2026 年 5 月
|
||||
**本轮版本**:v21(v20 基础上的延续审查)
|
||||
**历史 TD 累计**:50 个(v1–v20 全部修复)
|
||||
**本轮新 TD**:**0 个**
|
||||
**综合评分**:**9.86 / 10**(与 v20 持平,所有新审模块全部通过)
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
v21 延续 v20 的系统性审查,覆盖 v20 结束时尚未逐一阅读的所有剩余模块:
|
||||
|
||||
- 敌人 AI 行为节点(BD_* 系列)
|
||||
- 装备 / 护符效果(Equipment.Effects)
|
||||
- 任务 / 挑战 / 成就
|
||||
- 对话 / 剧情 / 事件链
|
||||
- 玩家状态机(Player.States)
|
||||
- 技能 / 法术 / 弹反
|
||||
- 世界系统(房间 / 谜题 / 遗骸)
|
||||
- VFX / 过场 / 摄像机
|
||||
- 存档辅助(崩溃检测 / 紧急存档 / 迁移)
|
||||
- Editor 工具(SOValidation / AddressGraph / BossSequenceViewer)
|
||||
|
||||
**本轮审查文件总计 41 个,全部通过——零缺陷。**
|
||||
|
||||
---
|
||||
|
||||
## 2. 本轮审查文件清单
|
||||
|
||||
### 2.1 敌人 AI 行为节点
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `BatchLOSSystem.cs` | ✅ 已在 v20 末尾确认 |
|
||||
| `BD_MoveTo.cs` | ✅ 已在 v20 末尾确认 |
|
||||
| `BD_IsPlayerVisible.cs` | ✅ 已在 v20 末尾确认 |
|
||||
|
||||
### 2.2 装备 / 护符效果
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `EquipmentManager.cs` | ✅ Clean |
|
||||
| `ICharmEffect.cs` | ✅ Clean |
|
||||
| `StatModifierEffect.cs` | ✅ Clean |
|
||||
| `WeaponOverrideEffect.cs` | ✅ Clean |
|
||||
| `OnHitEffect.cs` | ✅ Clean |
|
||||
| `AttackSpeedEffect.cs` | ✅ Clean |
|
||||
| `SoulSpellEffect.cs` | ✅ Clean |
|
||||
|
||||
### 2.3 任务 / 挑战 / 成就
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `QuestManager.cs` | ✅ Clean |
|
||||
| `ChallengeRoomManager.cs` | ✅ Clean |
|
||||
| `AchievementManager.cs` | ✅ Clean |
|
||||
|
||||
### 2.4 叙事 / 对话 / 事件链
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `DialogueManager.cs` | ✅ Clean |
|
||||
| `CutsceneManager.cs` | ✅ Clean |
|
||||
| `EventChainManager.cs` | ✅ Clean |
|
||||
|
||||
### 2.5 玩家状态机
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `IdleState.cs` | ✅ Clean |
|
||||
| `RunState.cs` | ✅ Clean |
|
||||
| `JumpState.cs` | ✅ Clean |
|
||||
| `FallState.cs` | ✅ Clean |
|
||||
| `WallSlideState.cs` | ✅ Clean |
|
||||
| `AerialDashState.cs` | ✅ Clean |
|
||||
| `ParryState.cs` | ✅ Clean |
|
||||
|
||||
### 2.6 技能 / 法术 / 弹反
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `SkillManager.cs` | ✅ Clean |
|
||||
| `SpellManager.cs` | ✅ Clean |
|
||||
| `ParrySystem.cs` | ✅ Clean |
|
||||
|
||||
### 2.7 世界系统
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `RoomController.cs` | ✅ Clean |
|
||||
| `RoomCamera.cs` | ✅ Clean |
|
||||
| `DeathShade.cs` | ✅ Clean |
|
||||
| `PuzzleSwitch.cs` | ✅ Clean |
|
||||
|
||||
### 2.8 动画 / VFX / 支撑系统
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `AnimationEventBinder.cs` | ✅ Clean |
|
||||
| `HitFXSpawner.cs` | ✅ Clean |
|
||||
| `AntiSoftlockSystem.cs` | ✅ Clean |
|
||||
|
||||
### 2.9 存档辅助
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `SaveMigrator.cs` | ✅ Clean |
|
||||
| `EmergencySaveService.cs` | ✅ Clean |
|
||||
| `CrashReporter.cs` | ✅ Clean |
|
||||
| `SettingsManager.cs` | ✅ Clean |
|
||||
|
||||
### 2.10 Boss 系统
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `EnemyPoiseComponent.cs` | ✅ Clean |
|
||||
| `BossSkillExecutor.cs` | ✅ Clean |
|
||||
|
||||
### 2.11 Editor 工具
|
||||
|
||||
| 文件 | 结论 |
|
||||
|------|------|
|
||||
| `SOValidationRunner.cs` | ✅ Clean |
|
||||
| `AddressReferenceGraphWindow.cs` | ✅ Clean |
|
||||
| `BossSkillSequenceWindow.cs` | ✅ Clean |
|
||||
|
||||
---
|
||||
|
||||
## 3. 各模块技术亮点汇总
|
||||
|
||||
### 3.1 装备 / 护符效果系统
|
||||
|
||||
**`EquipmentManager`**
|
||||
- `_usedNotches` 字段缓存避免 `LINQ Sum` 热路径开销;`_equipped` 操作时同步维护。
|
||||
- 返回值语义:`TryEquipCharm` 返回 `null`(成功)或错误字符串(失败),避免使用 `out bool` 双出参,UI 侧直接做非空判断,API 清晰。
|
||||
- `EquipmentContext` 结构体在 `Awake` 一次组装,传递给所有 `ICharmEffect.OnEquip/OnUnequip`,避免重复 `GetComponent`。
|
||||
|
||||
**`OnHitEffect`**
|
||||
- 通过 `IEventChannelRegistry.Get<HitConfirmedEventChannelSO>` 动态查找频道,无硬引用。
|
||||
- `_sub?.Dispose()` RAII 释放,卸下护符即自动取消订阅,零泄漏。
|
||||
- `KnockbackBoost` case 有明确注释说明实际逻辑在 `HurtBox` 流水线处理,此处为后续反馈预留——清晰诚实。
|
||||
|
||||
**`StatModifierEffect / AttackSpeedEffect / SoulSpellEffect`**
|
||||
- 全部 `[Serializable]`,在 SO 资产内联序列化,Inspector 直接配置。
|
||||
- 对称 `OnEquip/OnUnequip` 幂等设计,多次装卸不累积副作用。
|
||||
|
||||
### 3.2 任务 / 挑战系统
|
||||
|
||||
**`QuestManager`**
|
||||
- `_questIndex` 字典在 `Awake` 构建,将 `GetQuestSO(id)` 从 O(n) 线性搜索降为 O(1)。
|
||||
- 全事件驱动(不轮询):订阅 `EVT_EnemyDied / CollectiblePickup / SceneLoaded / NpcDialogueCompleted`,进度更新完全被动。
|
||||
- `IQuestManager` ServiceLocator 单例 + Awake 自毁防重复。
|
||||
|
||||
**`ChallengeRoomManager`**
|
||||
- 挑战开始前 `PreloadEnemyAssets` 用 `HashSet<string>` 去重,所有 Addressable 资源缓存就绪后才 `SpawnWave(0)`,消除第一波生成卡帧。
|
||||
- `_preloadHandles` 列表在 `OnDisable` 中全部 `Release`,无内存泄漏。
|
||||
- 自动快速存档于挑战开始时(失败读档回入口),挑战流程与存档系统低耦合。
|
||||
|
||||
### 3.3 叙事 / 对话 / 事件链
|
||||
|
||||
**`DialogueManager`**
|
||||
- `IsDialogueActive` 门卫防重入,`StartDialogue` 幂等安全。
|
||||
- `_inputReader.EnableUIInput()` / `EnableGameplayInput()` 围绕协程序列正确切换 Action Map,防止对话期间玩家移动。
|
||||
- `_onNpcDialogueCompleted.Raise(npcId)` 在序列结束时广播,`QuestManager` / `EventChainManager` 监听此事件,叙事→任务解耦。
|
||||
|
||||
**`CutsceneManager`**
|
||||
- `PlayCutscene(CutsceneSO, onCompleted?)` 回调式 API,播放完成后写存档 flag,无硬等待协程耦合。
|
||||
- `PlayById(string)` 通过 `_registeredCutscenes` 数组线性查找,数组通常 ≤10 个条目,线性可接受;若扩大至 50+ 可改 Dictionary(当前不必过度优化)。
|
||||
|
||||
**`EventChainManager`**
|
||||
- `#if UNITY_EDITOR` 静态 `OnChainExecutedInEditor` 事件供编辑器窗口推送日志,零运行时开销。
|
||||
- `OnEnable` 中先 `cond.ResetState()` 再 `cond.Register(this)`,防止 Domain Reload 跨 PlayMode 状态残留。
|
||||
|
||||
### 3.4 玩家状态机
|
||||
|
||||
**状态转换边界清晰**
|
||||
- `IdleState`:`IsGrounded`→`FallState`,`ConsumeJump()`→`JumpState`,`|MoveX|>0.1`→`RunState`
|
||||
- `RunState`:离地→`FallState`,缓冲跳→`JumpState`,停止→`IdleState`
|
||||
- `JumpState`:`velocity.y<=0`→`FallState`,`OnJumpCancelled()` 立即 `CutJump()`(可变跳高)
|
||||
- `FallState`:郊狼时间 + 缓冲跳→`JumpState`,着地→`Idle/Run`;`FallGravityMult` 增强下落感
|
||||
|
||||
**`AerialDashState`**
|
||||
- `_aerialDashesLeft` 计数,`ResetAerialDashes()` 由 `IdleState.OnStateEnter()` 在着地时调用,确保着地恢复次数。
|
||||
- 冲刺期间 `SetGravityScale(0f)` + `FixedUpdate` 锁速,`OnStateExit` 恢复 `DefaultGravityScale`,任何退出路径均安全。
|
||||
|
||||
**`WallSlideState`**
|
||||
- 用 `Input.JumpStartedEvent +=/-=` 代替 Update 内轮询,进入/退出状态时绑定/解绑,精确无漏。
|
||||
|
||||
**`ParryState`**
|
||||
- Animancer 动画 `OnEnd` 回调驱动退出,无魔法延迟秒数;无动画时即时退出——两路都处理。
|
||||
|
||||
### 3.5 技能 / 法术 / 弹反
|
||||
|
||||
**`SkillManager`**
|
||||
- 冷却更新用固定大小 `_activeSkills` 快照数组(不用 `List`),`UpdateSkillSet` 时重建,`Update` 内零 GC 遍历。
|
||||
- 形态切换时 `_cooldowns.Clear()` + 数组重建,冷却状态随形态切换完全重置。
|
||||
|
||||
**`SpellManager`**
|
||||
- 单槽设计简洁,`CooldownFraction` 属性供 UI 进度条使用,分离计算与展现。
|
||||
|
||||
**`ParrySystem`**
|
||||
- 五阶段枚举 `Inactive/Startup/Active/EndLag/CounterWindow`,状态语义清晰。
|
||||
- `OnParryConsumed` / `OnParryActivated` C# 事件供 PlayerController 订阅,`_onParrySuccess` SO 事件频道供 UI/反馈系统订阅——两层事件分工合理。
|
||||
- 程序集约束:`BaseGames.Parry` 不引用 `BaseGames.Combat`,`ConsumeParry()` 无 `DamageInfo` 参数,依赖方向清洁。
|
||||
|
||||
### 3.6 世界系统
|
||||
|
||||
**`PuzzleSwitch`**
|
||||
- 四种触发模式(InteractOnce / InteractToggle / Pressure / Hold)在单一组件内通过 `_mode` 枚举分支处理,无子类爆炸。
|
||||
- `WorldStateRegistry` SO 注入(非单例),支持多场景并行使用。
|
||||
- `_switchId` 空串时不持久化,设计者可灵活选择。
|
||||
|
||||
**`DeathShade`**
|
||||
- 实现 `IInteractable`,与通用交互系统无缝集成。
|
||||
- `Interact` 中 `_storedGeo > 0` 判断后广播,不向 `PlayerStats` 直接添加 Geo——事件解耦。
|
||||
|
||||
**`RoomCamera / RoomController`**
|
||||
- `OnEnable/OnDisable` 切换优先级激活/停用虚拟相机,由 GameObject active 状态驱动,零额外逻辑。
|
||||
|
||||
### 3.7 存档辅助
|
||||
|
||||
**`SaveMigrator`**
|
||||
- 静态 fall-through 迁移链,每个版本区间顺序落下,新版本只需追加 `if (v == "x.y")` 分支。
|
||||
- `IsOlderThan` 使用 `System.Version` 语义比较,无手写字符串分割。
|
||||
|
||||
**`EmergencySaveService`**
|
||||
- 监听 `_onGameplayActive` BoolEvent,非游戏中(加载 / 过场 / 主菜单)不触发紧急存档,避免脏数据。
|
||||
- `PromoteToSlot` 异步 API 供崩溃恢复 UI 调用。
|
||||
|
||||
**`CrashReporter`**
|
||||
- `MaxLogsPerSession = 5` 防异常风暴写爆磁盘。
|
||||
- `WriteDiagnosticLog` 同步 IO(崩溃场景 async 不可靠),空 `catch` 无二次抛出——唯一合理的吞异常场景。
|
||||
- `_cleanExit` flag + `OnApplicationPause` 区分正常退出与意外退出,移动端紧急存档准确触发。
|
||||
|
||||
### 3.8 BossSkillExecutor
|
||||
|
||||
- `_wfsCache` 静态字典缓存 `WaitForSeconds`,消除协程分配;
|
||||
- `[RuntimeInitializeOnLoadMethod(SubsystemRegistration)]` 清空缓存,Domain Reload Disabled 安全。
|
||||
- `InterruptCurrentSkill()` 精确 `StopCoroutine` + `FinishExecution()`,阶段切换不留悬空协程。
|
||||
|
||||
### 3.9 Editor 工具
|
||||
|
||||
**`SOValidationRunner`**
|
||||
- 实现 `IPreprocessBuildWithReport`(`callbackOrder = 1`),构建前自动校验所有 `IValidatable` SO,错误则 `BuildFailedException` 中止——生产安全门。
|
||||
- 菜单项 `Tools/Validate All ScriptableObjects` 供日常手动验证。
|
||||
|
||||
**`AddressReferenceGraphWindow`**
|
||||
- 扫描 `.cs` 文件中 `AddressKeys.X` 引用,检测孤儿 Key(有声明无引用)和无效 Key(有引用但不在 Addressables),CSV 导出,资产健康度可视化。
|
||||
|
||||
**`BossSkillSequenceWindow`**
|
||||
- 甘特图:Windup(黄)/ Active(红)/ Recovery(灰)/ VulnerabilityWindow(绿)时序可视化。
|
||||
- `DurationNormalized < 0.1` 时变红警告,设计者即时发现配置错误。
|
||||
- 拖放加载 + `EditorGUIUtility.PingObject` 高亮对应 SO,工作流友好。
|
||||
|
||||
---
|
||||
|
||||
## 4. 遗留非阻塞建议(历史延续)
|
||||
|
||||
| ID | 级别 | 位置 | 说明 |
|
||||
|----|------|------|------|
|
||||
| S7 | 提示 | `GameManager._deathScreenConfirmed` | 字段非死码,TD-48 修复后仍被正确使用,无需改动 |
|
||||
| S8 | 提示 | `SpringSystem.cs` | 空 TODO 存根,弹簧机制尚未实现 |
|
||||
| S9 | 提示 | `SaveManager.GetSlotSummaryAsync` | silent catch 建议添加 `Debug.LogWarning` |
|
||||
|
||||
---
|
||||
|
||||
## 5. 历史 TD 修复汇总(v1–v20)
|
||||
|
||||
| 版本 | 修复数 | 代表性修复 |
|
||||
|------|--------|------------|
|
||||
| v1–v9 | 25 | 核心架构问题、ServiceLocator 安全、GC 热路径 |
|
||||
| v10–v19 | 19 | UI 逻辑、存档系统、事件订阅泄漏、平台服务 |
|
||||
| v20 | 6 | TD-45 UIManager 死亡屏幕、TD-46 BGM空Clip、TD-47 TutorialManager注册时机、TD-48 DeathRespawnService 确认等待架构、TD-49 FloatingDamageText Camera.main、TD-50 HazardZone 未使用枚举 |
|
||||
| **合计** | **50** | |
|
||||
|
||||
---
|
||||
|
||||
## 6. 综合评分(v21 最终确认)
|
||||
|
||||
| 维度 | 分数 | 说明 |
|
||||
|------|------|------|
|
||||
| **架构设计** | 9.9 | SO 事件频道 + ServiceLocator + CompositeDisposable 三位一体;装备/技能/对话/事件链全部接口解耦 |
|
||||
| **性能** | 9.8 | 零 GC 热路径(DamageInfo struct Builder、BatchLOS swap-and-pop、SkillManager 快照数组、WFS缓存);少数 Update 逐帧扫描无法避免(AntiSoftlock velocity.magnitude 可改 sqrMagnitude) |
|
||||
| **可扩展性** | 9.9 | ICharmEffect / ILOSRequester / IPoiseSource / ISwitchable 全接口扩展点;护符效果序列化多态;EventChain SO 数据驱动 |
|
||||
| **编辑器友好** | 9.9 | SOValidationRunner 构建前校验、AddressReferenceGraphWindow 资产健康、BossSkillSequenceWindow 甘特图、`#if UNITY_EDITOR` EditorOwner 只读属性、NavSurface 快捷菜单 |
|
||||
| **使用便利性** | 9.8 | TryEquipCharm 字符串返回值清晰、ParrySystem 五阶段枚举、ChallengeRoomManager 自动预热 + 快存 |
|
||||
| **代码质量** | 9.8 | 命名一致、注释完整(中文)、调试 Assert 覆盖关键引用、#if 编译守卫正确使用 |
|
||||
| **框架纯净度** | 9.9 | 无兼容垫片、无遗留临时代码(除 SpringSystem stub)、接口 > 继承、数据逻辑一致 |
|
||||
|
||||
### **综合评分:9.86 / 10**
|
||||
|
||||
---
|
||||
|
||||
## 7. 结论
|
||||
|
||||
经过 v1–v21 共 **21 轮**系统性审查,覆盖项目 `Assets/Scripts` 下全部主要源文件(约 390+ 文件),累计发现并修复 **50 个 TD**(技术债务)。本轮 v21 新审 41 个文件,**零新缺陷**。
|
||||
|
||||
框架整体质量已达到商业项目发布标准:
|
||||
|
||||
- **架构层**:接口驱动、事件解耦、ServiceLocator 统一注册,无硬依赖循环。
|
||||
- **性能层**:热路径全面零 GC,批量 LOS 节流、对象池、WFS 缓存齐备。
|
||||
- **数据层**:SO 数据与运行时逻辑分离,IValidatable 构建前校验,SaveMigrator 版本链健壮。
|
||||
- **工具层**:Editor 窗口覆盖资产引用、Boss 技能时序、SO 校验,工作流自足。
|
||||
- **安全层**:EmergencySave + CrashReporter + AntiSoftlock 三重保障,防数据丢失与软锁。
|
||||
|
||||
唯一的遗留 TODO 是 `SpringSystem.cs`(弹簧机制空存根),属于功能尚未实现而非质量问题。
|
||||
Reference in New Issue
Block a user