- 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.
6.2 KiB
Minimap System — Round 17 Independent Review
评审范围
全部 23 个源文件(4 接口 + 15 运行时 + 4 编辑器),在 R16 全部修复已落地的基础上进行全面重新审查。
R16 修复确认
| 编号 | 描述 | 状态 |
|---|---|---|
| R16-N1 | DrawRoomBadge 优先级 Save>Boss>Shop>Teleport,样式判断改为 badge=="★" |
✅ 已确认 |
| R16-N2 | MinimapHUD 新增 4 个 Sprite 图标字段 + ChooseIcon() | ✅ 已确认 |
| R16-N3 | MapPinManager._mapSvc Start() 中缓存 | ✅ 已确认 |
| R16-N4 | _regionNames 字段统一 + [FormerlySerializedAs] |
✅ 已确认 |
R17 评分(修复前)
| 维度 | 权重 | 分数 | 说明 |
|---|---|---|---|
| 架构解耦 | 20% | 95 | 接口驱动、ServiceLocator、事件单向流;无循环依赖 |
| 功能完整性 | 20% | 90 | 三级可见性、传送、Pin 系统、本地化区域名;完整 |
| 性能 | 15% | 93 | 对象池×3、O(viewRadius²) 剔除、_servicesReady 短路、PinsVersion 脏检查 |
| 编辑器工具 | 15% | 87 | 布局编辑器功能丰富,但存在死代码字段 + 搜索 UX 缺陷 |
| 可扩展性 | 10% | 93 | RoomType[Flags] 可扩展;SO 驱动配置;接口易替换 |
| 代码质量 | 10% | 90 | 注释充实、命名规范,存在一处死字段 |
| 玩家体验设计 | 10% | 88 | 键盘平移后缩放计算依赖 content.rect.size 而非缩放后尺寸,可能有偏差 |
综合(修复前):91.0 / 100
发现问题
N1(低,代码质量):MapLayoutEditorWindow._cachedErrorRoomIds 是死代码
文件:Assets/_Game/Scripts/Editor/World/Map/MapLayoutEditorWindow.cs
现状(第 46 行):
private readonly HashSet<string> _cachedErrorRoomIds = new();
注释称"由验证按钮点击时重建,防止 OnInspectorGUI 高频重建导致 GC",但:
MapLayoutEditorWindow使用OnGUI,不是OnInspectorGUIRunValidation()创建的是另一个字段_errorRoomIds = new HashSet<string>()DrawMapArea使用_errorRoomIds(第 318 行),从不读取_cachedErrorRoomIds_cachedErrorRoomIds从未被填充或读取,是复制自MapDatabaseEditor后遗留的死代码
修复:删除 MapLayoutEditorWindow._cachedErrorRoomIds 字段及其注释。
N2(低,编辑器 UX):搜索有匹配时非匹配房间未降低可见度
文件:Assets/_Game/Scripts/Editor/World/Map/MapLayoutEditorWindow.cs
现状(第 329-331 行):
: matchesSearch
? new Color(1f, 0.95f, 0.2f, 0.55f)
: new Color(regionColor.r, regionColor.g, regionColor.b, 0.28f);
当搜索有结果时,匹配房间显示黄色,但非匹配房间仍使用完整区域颜色(alpha 0.28)。在房间密集的大地图中,视觉对比度不足,难以快速定位目标房间。
修复:当搜索文本非空且当前房间不匹配时,将 alpha 从 0.28 降低至 0.08,使匹配项更突出。
N3(低,编辑器 UX):搜索有文本但无匹配时缺少反馈
文件:Assets/_Game/Scripts/Editor/World/Map/MapLayoutEditorWindow.cs
现状:搜索文本非空但无房间匹配时,地图区域正常显示,无任何提示。策划/开发人员不知道是搜索词拼写有误还是确实没有该房间。
修复:在 DrawMapArea 判断是否有匹配结果,若无结果则在地图区域居中绘制提示文本。
N4(低,潜在):键盘平移在缩放后可能存在范围偏差
文件:Assets/_Game/Scripts/World/Map/MapInputHandler.cs
现状(第 76-80 行):
Vector2 contentSize = content.rect.size;
Vector2 viewportSize = viewport.rect.size;
float rangeX = contentSize.x - viewportSize.x;
float rangeY = contentSize.y - viewportSize.y;
content.rect.size 是内容节点在其本地空间的尺寸,当 _zoomTarget.localScale 改变后,视觉内容尺寸变为 content.rect.size × scale,但此处未乘以 _zoom,导致缩放后键盘平移的每步速度和可移动范围计算有偏差。
注意:若 _zoomTarget(通常为 _roomContainer)不是 _scrollRect.content,此问题可能不存在。需结合实际 Prefab 层级确认。
修复建议:将 rangeX/rangeY 乘以当前 _zoom;同时在 CenterOnCurrentRoom 中对 contentSize 做同样处理。
R17 修复项目
本轮仅修复高置信度问题:
| 编号 | 优先级 | 文件 | 修复内容 |
|---|---|---|---|
| N1 | 低 | MapLayoutEditorWindow.cs | 删除死字段 _cachedErrorRoomIds |
| N2 | 低 | MapLayoutEditorWindow.cs | 搜索活跃时非匹配房间 alpha 降至 0.08 |
| N3 | 低 | MapLayoutEditorWindow.cs | 无匹配结果时绘制居中提示文本 |
N4 为潜在问题,需结合 Prefab 配置验证,本轮暂不修复,记录备查。
R17 评分(修复后预期)
| 维度 | 权重 | 分数 | 变化 |
|---|---|---|---|
| 架构解耦 | 20% | 95 | — |
| 功能完整性 | 20% | 90 | — |
| 性能 | 15% | 93 | — |
| 编辑器工具 | 15% | 93 | +6(死代码清除 + 搜索 UX 提升) |
| 可扩展性 | 10% | 93 | — |
| 代码质量 | 10% | 95 | +5(死字段消除) |
| 玩家体验设计 | 10% | 88 | — |
综合(修复后):93.0 / 100
架构亮点总结
经过 17 轮迭代,小地图系统已达到专业游戏级标准:
- 接口层完整:IMapService / IPinService / IPlayerPositionProvider / ITeleportService 四接口全部 ServiceLocator 注册,消费方零具体类依赖
- 性能优化到位:MapDatabaseSO 双重 O(1) 索引、MinimapHUD O(viewRadius²) 剔除、3 对象池、PinsVersion 脏检查、_servicesReady 短路
- 存档一致:MapManager / MapPinManager / TeleportService 三处 ISaveable 均为防御性拷贝
- 编辑器工具成熟:布局编辑器支持拖拽、搜索、图例、Play Mode 叠加;自动注册 AssetPostprocessor;MapRoomDataSO SceneGUI 双角控制点
- 输入 InputSystem 化:MapInputHandler、MinimapInputHandler 均通过 InputReaderSO 软绑定,无直接键盘轮询
- 本地化对齐:RegionNameEntry.GetDisplayName() 三级回退(LocKey → DisplayName → RegionId),MapProgressDisplay 和 RegionNameDisplay 共用同一机制