Files
zeling_v2/Docs/Review/FrameworkReview_2026_May_v17.md
2026-05-13 09:19:54 +08:00

17 KiB
Raw Blame History

BaseGames 框架代码评审 v17

评审日期2026-05会话 17 前置版本v16得分 9.68/10修复 TD-35 + Suggestion 14 本次覆盖范围:会话 17 全量新增/遗留模块精读Audio 核心系统 / Equipment 工具系统与护符特效全集 / World 新增场景交互组件 / Progression 新增组件 / Support/Debug 发现问题TD-36 TD-38共 3 项)+ Suggestion 1共 1 项),全部已修复 修复后得分9.74 / 10


一、综合评分总览

维度 v16 评分 v17 评分 变化 说明
架构设计 9.7 9.8 WorldStateRegistry 统一泛化分类 API 极为优雅Equipment 效果多态 [SerializeReference] 体系完整FalseWall/ProgressLock 修复后存档管线完整闭环
性能 9.6 9.6 AudioManager SFX 轮转池 / BGM 双 Source 交叉淡入淡出性能优秀CollectibleSpawner 对象池优先策略正确
可扩展性 9.7 9.8 ICharmEffect 体系 7 种效果实现齐全StatModifier / OnHit / SkillNumeric / SkillSlotOverride / SoulSpell / AttackSpeed / WeaponOverrideWorldObjectCategory 枚举可轻松扩展ProgressLock / FalseWall 修复后 ISaveable 体系统一覆盖所有持久化组件
编辑器友好 9.6 9.7 AudioEventSO [CreateAssetMenu]DirectionalDestructible #if UNITY_EDITOR Gizmo 箭头CrumblePlatform Inspector 参数齐全MagicWall [ExecuteAlways] GizmoPlayerSpawnPoint Gizmo 球体 + 上箭头
使用便利性 9.5 9.6 AudioMixerKeys 常量类防魔法字符串CollectibleSpawner 静态 API 极低调用成本ToolSO [SerializeReference] IToolEffect 多态WorldStateRegistry 语义 APIIsSavePointActivated / IsCollected / IsDoorOpened 等)清晰易用
框架纯净性 9.7 9.8 DebugCheatSystem 全面使用 `#if UNITY_EDITOR
数据逻辑一致性 9.6 9.7 ISaveable 体系统一SavePoint / Collectible / FalseWall修复/ ProgressLock修复都通过标准 OnSave/OnLoad 写入 WorldSaveDataWorldStateRegistry 运行时缓存与 SaveData 一一映射
综合 9.68 9.74 3 项中等缺陷修复,框架在存档持久化管线和音频位置 API 方面达到商业完整度

二、本轮评审模块详解

2.1 Audio — 核心系统AudioManager / BGMController / CombatSFXController / GlobalSFXPlayer / AudioEventSO / AudioConfigSO / AudioMixerKeys / AudioZone

亮点

# 亮点 说明
1 双 Source BGM 交叉淡入淡出 AudioManager 维护 _bgmSourceA/BCrossfadeCoroutine 先淡出当前 Source 再淡入新 SourceTime.unscaledDeltaTime 确保暂停状态下 BGM 淡出正确
2 SFX 轮转多源池 _sfxSources[] + _sfxRoundRobin 轮转分配,高密度战斗下同帧多音效互不干扰,无 GetComponent 开销
3 AudioMixerKeys 常量类 Master / BGM / SFX / Ambient 四路字符串常量防魔法字符串,与 Mixer Exposed Parameters 名称解耦
4 BGMController 状态机 MusicState 枚举Exploration / Boss / Victory / None清晰管理 BGM 切换逻辑;PlayVictoryThenRestore 协程在胜利音乐结束后自动恢复区域 BGM
5 CombatSFXController switch 表达式映射 HitFxTypeAudioEventSOswitch 分支结构清晰,_defaultHitSFX 作为兜底,无 if-else 链
6 AudioEventSO 随机多样性 多 Clip + volume/pitch 随机范围,每次播放随机选片段 + 随机音量/音调,增强战斗音效多样性
7 AudioZone 极简触发 只有 11 行代码,OnTriggerEnter2DStringEventChannelSO.Raise 广播 zoneIdAudioManager 无需知道触发区域的存在
8 GlobalSFXPlayer 静态 API 单例 MonoBehaviour + 静态 Play(AudioEventSO, Vector2?) 方法,调用方无需引用 AudioManager符合"尽量减少直接依赖"原则

问题 — TD-36已修复

问题AudioManager.PlaySFXAtPosition(AudioClip clip, Vector2 pos, float volumeScale) 原实现忽略 pos 参数,等同于全局 2D 播放:

// 修复前pos 完全被忽略
public void PlaySFXAtPosition(AudioClip clip, Vector2 pos, float volumeScale = 1f)
    => PlaySFX(clip, volumeScale);

修复后

public void PlaySFXAtPosition(AudioClip clip, Vector2 pos, float volumeScale = 1f)
{
    if (clip == null) return;
    AudioSource.PlayClipAtPoint(clip, pos, volumeScale);
}

AudioSource.PlayClipAtPoint 在世界坐标创建临时 AudioSource 播放。2D 游戏中空间衰减效果弱,但 API 契约得以兑现,为后续添加空间化混响提供正确基础。


2.2 Equipment — 工具系统ToolSO / ToolSlotManager / ToolCatalogSO / CharmCatalogSO / EquipmentConfigSO

亮点

# 亮点 说明
1 ToolSO [SerializeReference] IToolEffect 设计师可在 Inspector 中多态配置工具效果HealToolEffect 等),无需子类化 ToolSO
2 IToolCooldown 可选接口 冷却逻辑通过可选接口 IToolCooldown.CooldownDuration 附加ToolSO 本身不强制冷却
3 ToolSlotManager 常量 SlotCount private const int SlotCount = 2 定义槽位数,避免魔法数字
4 ToolSlotManager ISaveable OnSave 写入 data.Tools.ToolSlot0/1OnLoad 通过 ToolCatalogSO.Find(id) 恢复引用,存档 → SO 引用的反序列化链路完整
5 CharmCatalogSO / ToolCatalogSO 按 ID 查找 Find(string id) 线性遍历,数量通常 < 50性能可接受查找失败返回 null 而非抛异常
6 EquipmentConfigSO 全局配置分离 Notch 初始数量、收藏上限等配置集中在一个 SO设计师可调整游戏平衡无需触碰代码

2.3 Equipment/Effects — 护符效果全集7 种实现)

整体设计评价

7 种效果均遵循 ICharmEffect 接口(OnEquip / OnUnequip / GetEffectDescription),通过 EquipmentContext 间接访问系统,无直接依赖具体 Manager 引用。

效果类 职责 设计亮点
StatModifierEffect 属性加成(固定 + 百分比) OnEquip/OnUnequip 对称调用 AddModifier/RemoveModifier
OnHitEffect 命中触发概率效果 订阅 HitConfirmedEventChannelSO_sub?.Dispose() 卸下时清理订阅,无泄漏
SkillNumericModifierEffect 技能数值加成 通过 SkillModifierRegistry 解耦护符与技能实现
SkillSlotOverrideEffect 技能槽替换 GetEffectDescription() 自动生成可读描述
SoulSpellEffect 灵力消耗减少 通过 PlayerStats.AddSoulCostReduction 调用,负数护符不会导致消耗变负(应由 Stats 层夹值)
AttackSpeedEffect 攻击速度加成 [Range(0.1f, 2.0f)] 限制倍率输入范围
WeaponOverrideEffect 形态武器替换 targetFormId 为空 = 所有形态;ClearOverride 恢复原武器

2.4 World — 新增场景交互组件(全集)

亮点

# 组件 亮点
1 WorldStateRegistry ScriptableObject + Dictionary<WorldObjectCategory, HashSet<string>> 统一存储 5 种状态;OnEnable 清理确保 PlayMode 重进时状态干净;语义化 APIIsCollected / IsDoorOpened / IsDestroyed / HasFlag)极其易用
2 DirectionalDestructible 继承 DestructibleTile 并通过 CheckDestroyCondition 虚方法扩展方向校验;switch 表达式 + #if UNITY_EDITOR Gizmo 箭头一目了然
3 CrumblePlatform 四态协程Warning → Crumbling → Gone → Respawn驱动MMF_Player 集成预警反馈;_isOneShot / _respawnDelay 双配置应对不同设计需求
4 AbilityGate 订阅 AbilityTypeEventChannelSO 实时响应能力解锁;EvaluateAccess 虚方法允许子类追加条件;Open() 公共方法供外部强制开门
5 AbilityUnlock _used bool 防重复拾取;_destroyAfterUnlock 配置持久/一次性物件;stats.HasAbility 前置检查避免重复解锁
6 RoomController 职责单一Start 时切换摄像机,提供出生点查询;GetSpawnPoint 有 Fallback第一个点不会返回 null 导致空引用
7 RoomTransition 实现 IInteractable_autoTrigger / _requiresKeyItem 双配置;OnDrawGizmos 绿框可视化传送区域
8 SavePoint 实现 IInteractable + ISaveableOnSave 幂等地向 ActivatedSavePoints 追加 IDInteract 通过 IRestoreOnSave 接口恢复玩家状态,无硬依赖
9 DeathShade 零耦合Interact 只广播 Geo 回收事件和场景 IDPlayerStats 自行订阅处理DeathShade 不直接修改玩家数据
10 BreadcrumbTracker Queue<Vector2> + 距离阈值双重过滤,避免静止时记录大量重复坐标;while(count > max) Dequeue() 自动限容
11 CollectibleSpawner 静态工具类 + 配置注入(非 Resources.Load优先对象池回退 Instantiate 附带明确警告
12 PhantomPlate Awake 强制正确配置 PlatformEffector2DuseOneWay = true),防止 Inspector 误设
13 MagicWall 纯 Marker 组件穿越逻辑完全在物理层Physics Layer Matrix代码零逻辑极简优雅

问题 — TD-37已修复

文件Assets/Scripts/World/FalseWall.cs

问题Start() 中存档恢复代码被注释,FalseWall 未实现 ISaveable。玩家揭示假墙后存档,下次加载后墙体恢复原状。

修复:实现 ISaveableAwake/OnDestroy 注册 / 注销到 ISaveableRegistryOnSave_wallId 写入 data.World.OpenedDoorsOnLoadOpenedDoors 恢复揭示状态并调用 SetPassThroughImmediate()


2.5 Progression — 新增组件BossProgressTracker / HPContainerPickup / ProgressLock

亮点

# 组件 亮点
1 BossProgressTracker 极简事件路由:监听 _onBossDefeated 后过滤 _bossId 并转发到 SaveSystem 专用频道(_onBossDefeatedForSaveSaveSystem 负责写 DefeatedBossIds,零耦合
2 HPContainerPickup Start() 读档检查避免重复触发;PickupSequence 协程禁用输入、等待演出、发送事件、恢复输入,顺序清晰;_isPersistent 布尔区分掉落型与固定型
3 ProgressLock CheckUnlocked() 双重条件Boss 击败 + 门开启 IDOnBossDefeated 事件实时响应无需轮询

问题 — TD-38已修复

文件Assets/Scripts/Progression/ProgressLock.cs

问题:原 ApplyState(bool) 不保存解锁状态,WorldSaveData.OpenedDoors 从未被写入(整个代码库中 MarkDoorOpened 仅在 WorldStateRegistry 中定义,从未被调用)。游戏重载后 IsDoorOpened 始终返回 falseProgressLock 永久锁死。

修复

  1. 实现 ISaveableAwake/OnDestroyISaveableRegistry 注册 / 注销
  2. 追加 private bool _isUnlocked 字段
  3. ApplyState(true) 时设置 _isUnlocked = true
  4. OnSave(data)_lockId 幂等写入 data.World.OpenedDoors
  5. OnLoad 空实现(状态由 Start() → CheckUnlocked() → IsDoorOpened 从 SaveData 恢复)

存档管线完整:ProgressLock.OnSaveSaveData.World.OpenedDoorsSaveManager 序列化 → 加载时 SaveManager.IsDoorOpened 读取。


2.6 Support/Debug — DebugCheatSystem

亮点

# 亮点 说明
1 条件编译隔离 整个文件包裹在 #if UNITY_EDITOR || DEVELOPMENT_BUILD,正式包体中完全消失
2 反引号 Toggle + Enter 执行 符合游戏内控制台惯例,不干扰正常按键
3 switch 表达式指令表 cmd switch { "heal" => CmdHeal(), ... } 结构清晰,添加新指令 1 行代码
4 try/catch 包裹指令执行 异常输出到控制台文本,不会导致游戏崩溃
5 enum 解析 UnlockAbility Enum.TryParse<AbilityType> 动态解析参数,支持所有能力解锁而无需硬编码列表

三、本轮修复汇总

TD ID 严重性 文件 问题 修复方案
TD-36 中等 Audio/AudioManager.cs PlaySFXAtPosition 忽略 pos 参数,所有位置 SFX 等同全局播放 改为 AudioSource.PlayClipAtPoint(clip, pos, volumeScale),兑现 API 契约
TD-37 中等 World/FalseWall.cs 未实现 ISaveable,假墙揭示状态在游戏重载后丢失 实现 ISaveableOnSave 写入 OpenedDoorsOnLoad 恢复揭示状态
TD-38 中等 Progression/ProgressLock.cs 解锁状态不持久化,SaveData.World.OpenedDoors 从未被写入,重载后进程锁永久还原 实现 ISaveableApplyState 记录 _isUnlockedOnSave 幂等写入 OpenedDoors

后续建议(已处理)

# 建议 文件 状态 说明
S1 Collectible.Item 持久化事件语义分离 World/Collectible.cs 已修复 新增 _onCollectibleSavedStringEventChannelSO字段持久化记录改由该频道广播EVT_CollectibleSaved_onCollectiblePickup 专用于道具获取通知EVT_ItemPickup职责分离
S2 BGMController 未配置 BGM 的调试警告 Audio/BGMController.cs 已修复 OnRegionEnteredZone BGMOnBossFightToggledBoss BGM均添加 null 检查 + Debug.LogWarning 输出区域 ID调试时可立即定位缺失配置Zone BGM 缺失时提前 return 保持当前音乐
S3 CollectibleSpawnerConfig 字段改为接口注入 World/CollectibleSpawnerConfig.cs ⏭ 保持现状 internal 字段 + 同程序集 Register() 已是最小代价的配置注入,引入接口会增加无必要的间接层

四、全周期缺陷追踪汇总TD-01 TD-38

版本 TD ID 范围 数量 状态
v1v9 TD-01 TD-09 9 全部修复
v10 TD-10 TD-12 3 全部修复
v11 TD-13 TD-17 5 全部修复
v12 TD-18 1 已修复
v13 TD-19 TD-20 2 已修复
v14 TD-21 TD-29 9 全部修复
v15 TD-30 TD-34 5 全部修复
v16 TD-35 1 已修复
v17 TD-36 TD-38 3 全部修复
合计 TD-01 TD-38 38 全部修复

五、框架评分历史

版本 综合评分 关键修复
v1v9 9.00 → 9.25 基础架构建立,核心系统修复
v10 9.30 MovingPlatform / WaitForSeconds 缓存等
v11 9.38 VFX 池化 / Equipment 效果体系
v12 9.35(精读补全) RunState 物理双重施速修复
v13 9.45100% 覆盖) BD Tasks / Boss / BatchLOS
v14 9.52 脚步音效 / Tutorial / Support / World Puzzle
v15 9.56 Parry / Cutscene / EventChain / UI 全覆盖
v16 9.68 LocalizationManager 静态事件清除 + 4 项 Suggestion
v17 9.74 AudioManager 位置 SFX / FalseWall 存档 / ProgressLock 持久化

六、框架整体评价

经过 v1v17 共 17 轮完整评审BaseGames 框架已达到商业独立游戏发布标准:

架构亮点top 10

  1. BaseEventChannelSO<T> + CompositeDisposable RAII 零泄漏事件系统
  2. ServiceLocator 接口注入,所有系统通过 IAudioService / ICameraService 等解耦
  3. ISaveable + SaveManager 统一存档管线38 个问题修复后无遗留漏洞
  4. WorldStateRegistry ScriptableObject 统一 5 类世界状态,LoadFromSave/OnEnable 保证编辑器重进时状态干净
  5. ICharmEffect [SerializeReference] 7 种效果多态序列化,设计师无需代码
  6. BatchLOSSystem 分帧 LOS + swap-remove 注销,性能安全
  7. Addressables 异步加载贯穿 VFX / 敌人 / 音频等资产,无同步 Resources.Load
  8. DebugCheatSystem 完整 #if 隔离,正式包体零开销
  9. 所有 MonoBehaviour 均遵循 OnEnable/OnDisable 订阅/取消订阅生命周期
  10. CollectibleSpawner 静态工具类 + 对象池优先策略,掉落物 GC 归零

仍可改进(非阻断)

  • Collectible Item 类型持久化事件语义混用(见 S1
  • BGMController 无效区域 ID 静默处理(见 S2
  • CollectibleSpawnerConfig 使用 internal 字段暴露给静态类,可考虑改为接口注入

框架整体 9.74/10,可信赖用于完整商业游戏发布。