Add independent review reports for Minimap system (Rounds 8, 9, and 26)

- 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.
This commit is contained in:
2026-05-25 23:15:12 +08:00
parent e2bc324905
commit f74d7f1877
53 changed files with 6825 additions and 270 deletions

View File

@@ -0,0 +1,150 @@
# 小地图系统 独立审查报告 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 / 100B+** |
> **相比 R1286.2/100**:发现 2 个遗留 BugN1 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()` 被遗漏。
```csharp
// ❌ 当前代码:未检查 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`,导致运行时异常。
```csharp
// ❌ 当前代码:无异常防护
_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` 组件订阅该方法
**修复**
1.`InputReaderSO` 添加 `CycleMinimapZoomEvent`
2. 新建 `MinimapInputHandler.cs` 组件,绑定按键 → `CycleZoom()`
---
### N4中等MapInputHandler 缺少"居中到玩家"快捷键
**文件**`MapInputHandler.cs``MapPanel.cs`
全屏地图打开后无"居中"快捷键(常见 UX 需求)。
`MapPanel.CenterOnCurrentRoom()``private`,外部无法调用。
**修复**
1.`InputReaderSO` 添加 `MapCenterEvent`
2.`CenterOnCurrentRoom()` 改为 `public`
3.`MapInputHandler.OnEnable/OnDisable` 中订阅
---
### FA缺失ITeleportService 无具体实现
**文件**`ITeleportService.cs`(接口已定义;无对应实现类)
定义了完整的传送服务接口,但无任何具体实现类。地图 UI 无法调用传送功能。
**修复**:新建 `TeleportService.cs`,实现 `ITeleportService`
- `CanTeleportTo`:检查解锁状态 + `IMapService.IsExplored`
- `RequestTeleport`:触发 `OnTeleportRequested` 事件 + 经由 `StringEventChannelSO` 驱动场景加载
- `ISaveable` 持久化已解锁传送点列表
---
## 已验证正常的项目
经本轮全量重读确认以下 R12 修复均完整到位:
| 项目 | 状态 |
|---|---|
| MapPanel Cell/Exit 对象池N1 | ✅ |
| DrawExitLines HashSet 去重N2 | ✅ |
| MapPinConfigSO + O(1) dict cacheN3 | ✅ |
| MapRoomAutoRegister null cleanupN4 | ✅ |
| HasCustomExitPos flag in MapLayoutEditorWindowN5 | ✅ |
| RegionNameDisplay O(1) dict lookupN6 | ✅ |
| _servicesReady 短路N7 | ✅ |
| 移除 OnMapUpdated 双重订阅N8 | ✅ |
| RoomFlags [Flags] 枚举兼容N9 | ✅ |
| PlayRevealAnim 协程FC | ✅ |
| CycleZoom() 方法存在FA — 但无绑定) | ⚠ 见 N3 |
| TryGetRoomAtWorldPosFB | ✅ |
| 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` |