- Round 8 report highlights improvements in architecture, editor usability, and data robustness, with a total score of 80/100. - Round 9 report focuses on editor extension capabilities, identifying issues with room data indexing and layout editing, resulting in a score of 76/100. - Round 26 report evaluates the system against commercial standards, noting new issues and confirming previous fixes, with a score of 95.8/100.
5.9 KiB
小地图系统 独立审查报告 Round 13
审查范围:Assets/_Game/Scripts/World/Map/(Runtime 17 文件)+
Assets/_Game/Scripts/Editor/World/Map/(Editor 4 文件)
对标标准:成熟 2D Metroidvania 类型游戏的专业编辑器扩展级别,
面向开发人员和策划人员,要求架构解耦、高性能、高可扩展性。
总评分
| 维度 | 满分 | 得分 | 说明 |
|---|---|---|---|
| 架构解耦 | 10 | 9.0 | 接口 + ServiceLocator 完整;唯一遗留:MapPin.cs 文件名与类名不符(历史问题) |
| 性能 | 10 | 9.0 | 对象池完整、dirty check 完整;FormatException 风险影响稳定性 |
| 编辑器 UX | 10 | 8.5 | 可视化布局编辑器完善;缺少快捷键说明与快速创建 |
| 数据模型 | 10 | 8.5 | RoomType [Flags] + HasCustomExitPos 完善;但 DrawExits 未使用 HasCustomExitPos |
| 输入系统 | 10 | 7.5 | InputReaderSO 对接完整;但 CycleZoom 无绑定、缺少"居中"快捷键 |
| 功能完整性 | 10 | 7.5 | ITeleportService 接口已定义但无实现 |
| 代码质量 | 10 | 9.0 | 注释质量高;MapProgressDisplay.Refresh() 缺少异常防护 |
| 可扩展性 | 10 | 9.0 | SO 驱动、Event Channel 解耦、Region 机制完善 |
| 总分 | 80 | 68.0 | 换算 100 分:85.0 / 100(B+) |
相比 R12(86.2/100):发现 2 个遗留 Bug(N1 DrawExits、N2 FormatException)和 3 个增强点,分数略有下调。修复后预计 91+。
Bug 发现
N1(严重):MapPanel.DrawExits() 忽略 HasCustomExitPos
文件:MapPanel.cs,DrawExits() 方法
问题:出口连接线的位置直接使用 exit.ExitGridPos * FullMapCellPixels,
未检查 HasCustomExitPos 标志。当策划未配置自定义出口坐标时,
ExitGridPos 默认为 Vector2Int.zero,所有连接线均渲染在 _roomContainer 原点 (0, 0) 处。
MapLayoutEditorWindow.DrawExitLines() 已在 R12 修复了同样问题,但 MapPanel.DrawExits() 被遗漏。
// ❌ 当前代码:未检查 HasCustomExitPos
conn.rectTransform.anchoredPosition = new Vector2(
exit.ExitGridPos.x * MapGridConstants.FullMapCellPixels,
exit.ExitGridPos.y * MapGridConstants.FullMapCellPixels);
// ✅ 修复:回退到方向中点
Vector2Int gridPos = exit.HasCustomExitPos
? exit.ExitGridPos
: GetExitFallbackGridPos(room, exit); // 按 ExitDirection 计算房间边缘中点
N2(中等):MapProgressDisplay.Refresh() 无 FormatException 防护
文件:MapProgressDisplay.cs,Refresh() 方法
问题:_globalFormat / _regionFormat 是 Inspector 可编辑字段;
策划填写错误格式字符串(如 {2} 超出参数范围)时,
string.Format(...) 抛出 FormatException,导致运行时异常。
// ❌ 当前代码:无异常防护
_globalProgressText.text = string.Format(_globalFormat, progress);
// ✅ 修复:try-catch + fallback
try { _globalProgressText.text = string.Format(_globalFormat, progress); }
catch (FormatException)
{ _globalProgressText.text = $"{progress:P0}";
Debug.LogWarning($"[MapProgressDisplay] 格式字符串错误:{_globalFormat}", this); }
增强点
N3(高优先):MinimapHUD.CycleZoom() 无输入绑定
文件:MinimapHUD.cs,CycleZoom() 方法
CycleZoom() 是一个 public 方法,设计意图是绑定到按键。但:
InputReaderSO没有CycleMinimapZoomEvent事件- 没有
MinimapInputHandler组件订阅该方法
修复:
- 在
InputReaderSO添加CycleMinimapZoomEvent - 新建
MinimapInputHandler.cs组件,绑定按键 →CycleZoom()
N4(中等):MapInputHandler 缺少"居中到玩家"快捷键
文件:MapInputHandler.cs,MapPanel.cs
全屏地图打开后无"居中"快捷键(常见 UX 需求)。
MapPanel.CenterOnCurrentRoom() 为 private,外部无法调用。
修复:
- 在
InputReaderSO添加MapCenterEvent - 将
CenterOnCurrentRoom()改为public - 在
MapInputHandler.OnEnable/OnDisable中订阅
FA(缺失):ITeleportService 无具体实现
文件:ITeleportService.cs(接口已定义;无对应实现类)
定义了完整的传送服务接口,但无任何具体实现类。地图 UI 无法调用传送功能。
修复:新建 TeleportService.cs,实现 ITeleportService:
CanTeleportTo:检查解锁状态 +IMapService.IsExploredRequestTeleport:触发OnTeleportRequested事件 + 经由StringEventChannelSO驱动场景加载ISaveable持久化已解锁传送点列表
已验证正常的项目
经本轮全量重读确认以下 R12 修复均完整到位:
| 项目 | 状态 |
|---|---|
| MapPanel Cell/Exit 对象池(N1) | ✅ |
| DrawExitLines HashSet 去重(N2) | ✅ |
| MapPinConfigSO + O(1) dict cache(N3) | ✅ |
| MapRoomAutoRegister null cleanup(N4) | ✅ |
| HasCustomExitPos flag in MapLayoutEditorWindow(N5) | ✅ |
| RegionNameDisplay O(1) dict lookup(N6) | ✅ |
| _servicesReady 短路(N7) | ✅ |
| 移除 OnMapUpdated 双重订阅(N8) | ✅ |
| RoomFlags [Flags] 枚举兼容(N9) | ✅ |
| PlayRevealAnim 协程(FC) | ✅ |
| CycleZoom() 方法存在(FA — 但无绑定) | ⚠ 见 N3 |
| TryGetRoomAtWorldPos(FB) | ✅ |
| CreatePinAtWorldPos 扩展(FE) | ✅ |
| MapProgressDisplay 组件存在(FF) | ⚠ 见 N2 |
实现计划
| 编号 | 改动 | 文件 |
|---|---|---|
| N1 | DrawExits 使用 HasCustomExitPos + 方向回退 | MapPanel.cs |
| N2 | Refresh() FormatException 防护 | MapProgressDisplay.cs |
| N3 | CycleMinimapZoomEvent + MinimapInputHandler | InputReaderSO.cs、新建 MinimapInputHandler.cs |
| N4 | MapCenterEvent + 公开 CenterOnCurrentRoom | InputReaderSO.cs、MapPanel.cs、MapInputHandler.cs |
| FA | TeleportService 具体实现 | 新建 TeleportService.cs |