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,232 @@
# 小地图系统独立评审 Round 21
**评审时间**R21基于 R20 全部修复已落地的代码基线)
**评审范围**`Assets/_Game/Scripts/World/Map/` 全部 19 个运行时文件 + 4 个编辑器扩展文件
**评分基准**:专业 2D Metroidvania 编辑器扩展标准(架构解耦 / 高性能 / 可扩展 / 开发者友好)
---
## R20 修复确认
| 编号 | 内容 | 状态 |
|------|------|------|
| R20-N1 | `RunRevealAnim` 包装协程,完成后 `_revealCoroutines.Remove(roomId)` | ✅ 确认L214-218 |
| R20-N2 | `ChooseDisplayIcon` 集中到 `MapRoomDataSO`MapPanel/MinimapHUD 改单行委托 | ✅ 确认L61-69 / L478-480 / L367-368 |
---
## 各维度评分
### 1. 架构设计Architecture 18.5 / 20
**亮点**
- ServiceLocator + 4 接口层IMapService / IPinService / IPlayerPositionProvider / ITeleportService完全解耦
- 事件驱动C# Action无轮询
- ISaveable 三处防御性拷贝对称实现
- MapRoomCellUI 在 MapPanel / MinimapHUD 共享,零重复 Prefab
- `ChooseDisplayIcon` R20-N2 后唯一入口,无漂移风险
**新发现问题 N1中等严重**`MinimapHUD` 缺少 LateUpdate 服务重试机制
`MapPanel.LateUpdate` 对未就绪的服务执行重试:
```csharp
// MapPanel.cs L169-170
if (!_servicesReady)
SubscribeServices();
```
`MinimapHUD` 仅在 `Awake``OnEnable` 中调用 `SubscribeServices()`**无 LateUpdate 重试**。
`MapPlayerTracker`IPlayerPositionProvider`[DefaultExecutionOrder]`,初始化顺序不确定:
-`MinimapHUD.Awake` 先于 `MapPlayerTracker.Awake` 执行 → `_playerProvider` 永久为 null
- 后果:玩家圆点不渲染,`OnRoomChanged` 永不触发HUD 完全静止
**扣分1.5**
---
### 2. 性能Performance 19.5 / 20
**亮点**
- MapPanel 3 对象池Cell / Pin / ExitMinimapHUD 2 对象池Cell / Pin
- O(viewRadius²) 空间索引查询(共享 `MapDatabaseSO._cellToRoom`
- `_servicesReady` 短路MapPanel消除每帧 ServiceLocator 查询
- `_revealCoroutines` 自清理R20-N1
- 复用缓冲区:`_toRemove` / `_roomsInViewBuffer` / `_newlyAddedBuffer`
- PinsVersion 脏检查 + 玩家位置脏检查
- `_regionCache` 懒加载,避免 LINQ 全扫
**说明**(信息级,不扣分):`MapPanel.BuildGrid` 末尾调用 `LayoutRebuilder.ForceRebuildLayoutImmediate`
`_scrollRect.content` 含 ContentSizeFitter此调用是必要的确保 `CenterOnCurrentRoom` 读到正确 content 尺寸);无 LayoutGroup 时代价极低。设计合理。
**扣分0.5**MinimapHUD 无 _servicesReady 短路,每次 OnEnable 均执行三次 ServiceLocator 查询)
---
### 3. 代码质量Code Quality 18.5 / 20
**亮点**
- `CurrentZoom` 属性R19-N1消除双份状态
- `RunRevealAnim` 自清理协程R20-N1
- `ChooseDisplayIcon` 单一职责集中R20-N2
- OnValidate RoomFlags 迁移兼容
- `HasCustomExitPos` 语义布尔替代哨兵值
- `[Obsolete]` + `[HideInInspector]` 废弃字段注解完整
**新发现问题 N2轻微**`MapPanel` 集合字段缺少 `readonly` 修饰
`MinimapHUD` 同类字段已标 `readonly`,两者不一致:
```csharp
// MinimapHUD.cs已正确标注
private readonly Dictionary<string, MapRoomCellUI> _cells = new();
private readonly List<Image> _pinImages = new();
private readonly Stack<Image> _pinPool = new();
private readonly Stack<MapRoomCellUI> _cellPool = new();
// MapPanel.cs缺少 readonly可被意外重新赋值
private Dictionary<string, MapRoomCellUI> _cells = new();
private List<Image> _pinImages = new();
private Stack<Image> _pinPool = new();
private Stack<MapRoomCellUI> _cellPool = new();
private Stack<Image> _exitPool = new();
private List<Image> _exitImages= new();
```
`_revealCoroutines` 已正确标 `readonly`,其余集合字段漏标。
**扣分1.0**N2 readonly 不一致)+ **0.5**MapInputHandler `_zoom``OnScroll` 仍作为局部累加器,与 `_zoomTarget.localScale.x` 功能重叠,配置错误时存在漂移风险)
---
### 4. 编辑器扩展Editor Tools 14.5 / 15
**亮点**
- `MapLayoutEditorWindow`:缩放/平移/拖拽/搜索/区域着色/验证/Undo/热改
- `_cachedZoomForStyle` 脏检查Style 不在每帧重建
- `_noResultStyle` 首次初始化缓存R18-N2
- `MapDatabaseEditor``MapRoomDataEditor``MapRoomAutoRegister` 覆盖完整工作流
- `DrawExitLines` 去重缓存(`_drawnExitPairs`
**扣分0.5**(信息级:`MapLayoutEditorWindow` 无单元测试覆盖)
---
### 5. 功能完整性Feature Completeness 14.5 / 15
**亮点**
- 三级可见性Unknown / Explored / Mapped完整实现
- 类型图标优先级Override > SavePoint > Boss > Shop > Teleport
- Pin 系统(持久化、类型化、可视半径内渲染)
- 出口连接线 + Fallback 位置R13-N1
- 区域检测与 RegionChanged 事件
- 存档/读档ISaveable
- 房间发现动画RevealAnim 自清理)
- 全屏地图 + 角落 HUD 双视图
**N1 影响**:若 MinimapHUD 初始化顺序不利,玩家圆点和 HUD 响应将缺失,属功能可靠性问题。**扣分0.5**
---
### 6. 输入系统Input System 9.5 / 10
**亮点**
- 全部使用 InputSystemInputReaderSO
- `MapInputHandler`Navigate / MapCenter / OnScroll
- `MinimapInputHandler`CycleMinimapZoom
- OnEnable/OnDisable 对称订阅/取消
**扣分0.5**(信息级:`MapInputHandler._zoom``_panel.CurrentZoom` 职责轻微重叠)
---
## 综合评分
| 维度 | 满分 | 得分 |
|------|------|------|
| 架构设计 | 20 | 18.5 |
| 性能 | 20 | 19.5 |
| 代码质量 | 20 | 18.5 |
| 编辑器扩展 | 15 | 14.5 |
| 功能完整性 | 15 | 14.5 |
| 输入系统 | 10 | 9.5 |
| **合计** | **100** | **95.0** |
> R21 较 R2094.2)略有提升,主要因 R20 修复全部落地确认;
> N1服务重试缺失是本轮最高优先级问题。
---
## 问题清单与修复建议
### N1 — MinimapHUD 缺少服务重试(高优先级)
**根因**`MapPlayerTracker``[DefaultExecutionOrder]`,可能晚于 `MinimapHUD` 注册服务。
**修复方案 A推荐防御性最强**:在 `MinimapHUD.LateUpdate` 中补充重试。
```csharp
// MinimapHUD.cs
private bool _servicesReady;
private void LateUpdate()
{
if (!_servicesReady)
SubscribeServices();
UpdatePlayerDot();
RenderPinsIfDirty();
}
private void SubscribeServices()
{
// 原有逻辑不变,末尾加:
if (_playerProvider != null && _mapSvc != null && _pinService != null)
_servicesReady = true;
}
```
**修复方案 B互补**:给 `MapPlayerTracker` 加执行顺序,确保早于无顺序 MonoBehaviour 注册。
```csharp
[DefaultExecutionOrder(-600)] // 晚于 MapManager(-700),早于默认 0
public class MapPlayerTracker : MonoBehaviour, IPlayerPositionProvider
```
**建议两个方案同时实施**B 保证常规路径A 防御异常路径。
---
### N2 — MapPanel 集合字段缺少 `readonly`(低优先级)
**修复**:在 `MapPanel.cs` 的集合字段声明处补充 `readonly`
```csharp
private readonly Dictionary<string, MapRoomCellUI> _cells = new();
private readonly List<Image> _pinImages = new();
private readonly Stack<Image> _pinPool = new();
private readonly Stack<MapRoomCellUI> _cellPool = new();
private readonly Stack<Image> _exitPool = new();
private readonly List<Image> _exitImages= new();
```
---
### N3 — MinimapHUD.OnDisable 未重置 `_servicesReady`(伴随 N1 修复引入)
实施 N1 修复后,若 `_servicesReady` 不在 `UnsubscribeServices` / `OnDestroy` 时重置,销毁后重建场景的实例将跳过重订阅。
```csharp
private void UnsubscribeServices()
{
_servicesReady = false; // 补充
// 其余原有逻辑不变
}
```
---
## 评分历史
| 轮次 | 评分 | 关键改动 |
|------|------|----------|
| R14 | 92.3 | — |
| R15 | 91.3 | — |
| R16 | 92.5 | — |
| R17 | 93.0 | — |
| R18 | 93.8 | MinimapHUD 废弃 _onMapUpdated 订阅 |
| R19 | 93.8 | CurrentZoom 属性_revealCoroutines 防泄漏 |
| R20 | 94.2 | RunRevealAnim 自清理ChooseDisplayIcon 集中 |
| **R21** | **95.0** | R20 修复确认;识别 N1服务重试缺失N2readonlyN3执行顺序 |