Files
zeling_v2/Docs/Review/Minimap_Review_Round13_Independent.md
T
joywayer f74d7f1877 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.
2026-05-25 23:15:12 +08:00

151 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 小地图系统 独立审查报告 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` |