Files
zeling_v2/Docs/Review/Minimap_Review_Round16_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

143 lines
7.3 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 16
> **评审范围**`Assets/_Game/Scripts/World/Map/`19个运行时文件)+
> `Assets/_Game/Scripts/Editor/World/Map/`4个编辑器文件)
> **基线**:R15 所有修复已验证到位(DrawRoomBadge TeleportStation、MapProgressDisplay 本地化、MapInputHandler normalizedPosition
> **评审标准**:2D 横版探索类游戏(银河恶魔城类型)小地图的架构、性能、编辑器、可扩展性综合标准
---
## 一、各维度评分(R16 当前状态)
| 维度 | 分值 | 说明 |
|---|---|---|
| 架构解耦 | 10/10 | 全接口驱动(IMapService / IPinService / IPlayerPositionProvider / ITeleportService),ServiceLocator 零硬依赖,事件频道单向通信 |
| 性能 | 9/10 | 3 对象池(MapPanel+ 2 对象池(MinimapHUD),O(1) 空间索引,PinsVersion 脏检查,O(viewRadius²) 剔除,dirty 标志避免无效重建 |
| 编辑器扩展 | 8/10 | MapLayoutEditorWindow 功能完整、可视化拖拽;**N1DrawRoomBadge 优先级与运行时 ChooseIcon 不一致,存在误导** |
| 数据模型 | 9.5/10 | RoomType[Flags] 语义清晰,RoomExitData.HasCustomExitPos 消除哨兵值歧义,双重 O(1) 索引,MapRoomAutoRegister 自动化注册 |
| 存档系统 | 9.5/10 | 正确 ISaveable 签名(OnSave/OnLoad),防御性 List 拷贝,UnlockedTeleportRoomIds 完整,PinsVersion 存档后自增 |
| UI 完整性 | 8/10 | MapPanel 支持 4 种类型图标(存档/Boss/商店/传送);**N2MinimapHUD 始终传 null icon,小地图无房间类型图标** |
| 输入系统 | 9.5/10 | 完整 InputSystem 迁移,CycleMinimapZoomEvent / MapCenterEvent 软绑定,normalizedPosition 防越界 |
| 可扩展性 | 9/10 | PinType 扩展 MapPinConfigSO 即可,RoomType [Flags] 追加 bitRegionNameEntry 通用机制 |
| 代码质量 | 8.5/10 | 注释详尽,防御性编程完善;**N3MapPinManager.CreatePin 未缓存 IMapServiceN4:同类型字段名不一致** |
| 本地化 | 8.5/10 | RegionNameDisplay 和 MapProgressDisplay 均有本地化,机制共用;N4 字段名差异影响策划工作流 |
**R16 综合评分(修复前):89.0 / 100**
---
## 二、发现问题(4 项)
### N1(中):`DrawRoomBadge` 优先级与运行时 `ChooseIcon` 不一致
**文件**`MapLayoutEditorWindow.cs` 第 464 行
**位置**`DrawRoomBadge` 函数
**现象**
```csharp
// 编辑器 DrawRoomBadge 当前顺序:
string badge = isBoss ? "★" : isSave ? "♦" : isTeleport ? "⇅" : "¥";
// Boss 第1 Save 第2 Teleport 第3 Shop 第4
// 运行时 MapPanel.ChooseIcon 顺序:
if (room.RoomFlags.HasFlag(RoomType.SavePoint) || room.IsSavePoint) return _iconSavePoint; // 第1
if (room.RoomFlags.HasFlag(RoomType.BossRoom) || room.IsBossRoom) return _iconBossRoom; // 第2
if (room.RoomFlags.HasFlag(RoomType.Shop) || room.IsShop) return _iconShop; // 第3
if (room.RoomFlags.HasFlag(RoomType.TeleportStation)) return _iconTeleport; // 第4
```
**影响**:当房间同时含 `SavePoint + BossRoom` flags 时,编辑器显示 ★(Boss),运行时显示 ♦(Save),严重误导策划检查地图标注结果。
**修复**:将 `DrawRoomBadge` 的优先级对齐运行时顺序:Save > Boss > Shop > Teleport。
---
### N2(中):`MinimapHUD` 始终传 `null` 作为格子图标
**文件**`MinimapHUD.cs` 第 333 行
**位置**`RefreshView` > 格子创建分支
**现象**
```csharp
cell.Setup(room, _mapSvc.GetVisibility(room.RoomId), null); // 第三个参数始终 null
```
`MapPanel.ChooseIcon` 完整支持存档点/Boss/商店/传送站 4 种图标,但 MinimapHUD 完全不传图标。玩家在小地图上看不到任何特殊房间标识,与全屏地图视觉不对称。
**修复**:在 MinimapHUD 添加与 MapPanel 对齐的 4 个 Sprite 字段和 `ChooseIcon` 方法,Setup 调用传入实际图标。
---
### N3(低):`MapPinManager.CreatePin` 每次调用 ServiceLocator
**文件**`MapPin.cs` 第 80 行
**现象**
```csharp
var mapSvc = ServiceLocator.GetOrDefault<IMapService>(); // 每次 CreatePin 都查
```
所有其他服务(MapManager、MinimapHUD 等)均在 `Awake`/`Start` 缓存 ServiceLocator 引用。MapPinManager 是唯一例外。存档加载后如需重新创建多个 Pin,每次都触发一次 ServiceLocator 查找。
**修复**:添加 `_mapSvc` 私有字段,在 `Start()` 中缓存,`CreatePin` 直接使用缓存引用。
---
### N4(低):`MapProgressDisplay._regionNameEntries` 与 `RegionNameDisplay._regionNames` 字段名不一致
**文件**`MapProgressDisplay.cs` 第 29 行 vs `RegionNameDisplay.cs`
**现象**:两者均使用 `RegionNameEntry[]` 配置区域本地化,但 Inspector 字段名不同:
- `RegionNameDisplay``_regionNames`(渲染区域名时查)
- `MapProgressDisplay``_regionNameEntries`R15 新增)
策划为两个组件配置同一份数据时需记忆两个不同字段名,破坏工作流一致性。
**修复**:将 `MapProgressDisplay._regionNameEntries` 重命名为 `_regionNames`,加 `[UnityEngine.Serialization.FormerlySerializedAs("_regionNameEntries")]` 保持序列化兼容。
---
## 三、已确认正常的项目
| 项目 | 结论 |
|---|---|
| R15-N1 DrawRoomBadge TeleportStation | ✅ 已添加 isTeleport 分支 |
| R15-N2 MapProgressDisplay 本地化 | ✅ _regionDict O(1) 查找 + BuildRegionDict() |
| R15-N3 MapInputHandler normalizedPosition | ✅ Clamp01 防越界 |
| R14-N1 TeleportService ISaveable 签名 | ✅ OnSave/OnLoad 正确实现 |
| R14-N2 TeleportStation RoomType flag + MapPanel icon | ✅ 1<<5 bit 位,_iconTeleport |
| MapDatabaseSO 双重索引 | ✅ string→room + Vector2Int→roomId 均 O(1) |
| PinsVersion 脏检查 | ✅ MapPanel/MinimapHUD 均使用 |
| MapRoomAutoRegister AssetPostprocessor | ✅ 自动注册 + EditorPrefs 开关 |
| MapPanel._servicesReady 短路优化 | ✅ 三服务就绪后跳过 LateUpdate 查询 |
| DrawExitLines GC 缓存 | ✅ _drawnExitPairs + ExitLineColor 已为 class fields |
| MapInputHandler.OnScroll 以鼠标为缩放中心 | ✅ pivotBefore/pivotAfter 补偿正确 |
| MapPlayerTracker 单例保护 | ✅ Awake 检测重复实例 |
| RegionNameDisplay 本地化回退链 | ✅ LocKey → DisplayName → RegionId 三级回退 |
---
## 四、修复后预估评分
| 修复 | 增量 |
|---|---|
| N1 修复:DrawRoomBadge 优先级对齐 | +1.0 |
| N2 修复:MinimapHUD 支持类型图标 | +1.5 |
| N3 修复:MapPinManager 缓存 IMapService | +0.5 |
| N4 修复:字段名统一为 _regionNames | +0.5 |
**R16 修复后预估评分:92.5 / 100**
---
## 五、架构总结
经过 16 轮迭代,小地图系统已达到成熟商业品质:
- **零具体类依赖**:所有模块间通信经由接口 + ServiceLocator + 事件频道
- **编辑器支持完整**:可视化布局编辑、自动注册、实时验证、场景覆盖
- **性能基础扎实**:5 个对象池、O(1) 空间查询、多层 dirty flag 机制
- **存档健壮**:防御性拷贝、版本化 PinsVersion、探索状态完整持久化
- **输入系统现代化**:全 InputSystem 软绑定,键盘/手柄/鼠标三路径均正确
主要剩余改进空间:UI 入场/出场过渡动画(属 UIManager 层职责,在本模块范围外)。