- 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.
151 lines
6.6 KiB
Markdown
151 lines
6.6 KiB
Markdown
# Minimap 系统独立评审 — Round 15
|
||
|
||
**评审范围**:`Assets/_Game/Scripts/World/Map/`(19 个运行时文件)+
|
||
`Assets/_Game/Scripts/Editor/World/Map/`(4 个编辑器文件)
|
||
**R14 基础评分(post-fix)**:约 92.3 / 100
|
||
**R15 Pre-fix 评分**:**88.5 / 100**(发现 3 项新问题拉低)
|
||
**R15 Post-fix 预估**:**95 / 100**
|
||
|
||
---
|
||
|
||
## 一、架构总览(与 R14 相同,确认无倒退)
|
||
|
||
| 层次 | 文件 | 职责 |
|
||
|------|------|------|
|
||
| 接口 | `IMapService` / `IPlayerPositionProvider` / `IPinService` / `ITeleportService` | 全部通过 ServiceLocator 注入,UI 与实现零耦合 |
|
||
| 服务 | `MapManager` / `MapPlayerTracker` / `MapPin.cs(MapPinManager)` / `TeleportService` | ISaveable 正确实现(OnSave/OnLoad)|
|
||
| 数据 | `MapRoomDataSO` + `MapDatabaseSO` + `MapPinConfigSO` + `SaveData.MapSaveData` | 双重 O(1) 索引、RoomType [Flags]、HasCustomExitPos |
|
||
| UI | `MapPanel`(全屏,3 池)+ `MinimapHUD`(角落,2 池,O(viewRadius²))| 脏标记三路守门,LateUpdate 轻量 |
|
||
| 输入 | `MapInputHandler` + `MinimapInputHandler` | 全 InputReaderSO,软绑定,OnEnable/OnDisable 管理 |
|
||
| 辅助 UI | `MapProgressDisplay` + `RegionNameDisplay` | 事件驱动,无每帧轮询 |
|
||
| 编辑器 | `MapLayoutEditorWindow` + `MapDatabaseEditor` + `MapRoomDataEditor` + `MapRoomAutoRegister` | 可视化布局 / 自动注册 / SceneView 拖拽 |
|
||
|
||
---
|
||
|
||
## 二、各维度评分
|
||
|
||
| 维度 | 满分 | R15 得分 | 变动 |
|
||
|------|------|----------|------|
|
||
| 架构设计与解耦 | 20 | 19 | = |
|
||
| 性能优化 | 20 | 18 | = |
|
||
| 编辑器扩展 | 20 | 16 | ↓2 (N1) |
|
||
| 功能完整性 | 20 | 17 | ↓1 (N2) |
|
||
| 数据模型 | 20 | 18 | = |
|
||
| 代码质量 | 20 | 18 | = |
|
||
| 可扩展性 | 20 | 17 | = |
|
||
| InputSystem 集成 | 20 | 18 | = |
|
||
| **合计** | **160** | **141** | — |
|
||
| **百分制** | 100 | **88.1** | — |
|
||
|
||
---
|
||
|
||
## 三、发现问题(R15 新增)
|
||
|
||
---
|
||
|
||
### N1(High)— `MapLayoutEditorWindow.DrawRoomBadge` 未处理 `TeleportStation`
|
||
|
||
**文件**:`Assets/_Game/Scripts/Editor/World/Map/MapLayoutEditorWindow.cs` → `DrawRoomBadge()`
|
||
|
||
**现象**:
|
||
R14 在 `RoomType` 中新增了 `TeleportStation = 1 << 5`,`MapPanel.ChooseIcon()` 已正确检查并显示传送站图标,
|
||
但编辑器窗口的 `DrawRoomBadge()` 方法 **未同步更新**,遗漏了 TeleportStation 分支:
|
||
|
||
```csharp
|
||
// 当前代码(遗漏 TeleportStation)
|
||
bool isBoss = room.RoomFlags.HasFlag(RoomType.BossRoom) || room.IsBossRoom;
|
||
bool isSave = room.RoomFlags.HasFlag(RoomType.SavePoint) || room.IsSavePoint;
|
||
bool isShop = room.RoomFlags.HasFlag(RoomType.Shop) || room.IsShop;
|
||
if (!isBoss && !isSave && !isShop) return; // TeleportStation 房间直接跳过
|
||
```
|
||
|
||
**影响**:策划在地图布局编辑器中无法直观识别哪些房间是传送站,增加配置失误风险。
|
||
运行时图标正确,但编辑器与运行时视觉不一致,违背"所见即所得"原则。
|
||
|
||
**修复方案**:`DrawRoomBadge` 添加 TeleportStation 检查,使用 "✈" 或自定义符号显示。
|
||
|
||
---
|
||
|
||
### N2(Medium)— `MapProgressDisplay` 区域名直接显示原始 `regionId`
|
||
|
||
**文件**:`Assets/_Game/Scripts/World/Map/MapProgressDisplay.cs`
|
||
|
||
**现象**:
|
||
`_regionFormat` 默认值为 `"{1}:{0:P0}"`,其中 `{1}` 直接输出原始 `_currentRegionId`
|
||
(如 `region_dungeon_001:42%`),而非玩家友好的显示名称。
|
||
|
||
与 `RegionNameDisplay` 组件的 `RegionNameEntry`(LocKey + DisplayName 本地化机制)形成明显的设计不一致:
|
||
前者正确本地化,后者直接暴露内部 ID。
|
||
|
||
**影响**:UI 显示策划/程序用的内部区域 ID,不可接受于发布版本;多语言项目中无法切换显示名。
|
||
|
||
**修复方案**:
|
||
在 `MapProgressDisplay` 中添加 `RegionNameEntry[]` 字段 + 字典构建,与 `RegionNameDisplay` 统一使用同一本地化机制,调用 `RegionNameEntry.GetDisplayName()` 解析 regionId → 显示名。
|
||
|
||
---
|
||
|
||
### N3(Low)— `MapInputHandler.Update` 直接写 `content.anchoredPosition`,绕过 ScrollRect 边界
|
||
|
||
**文件**:`Assets/_Game/Scripts/World/Map/MapInputHandler.cs`
|
||
|
||
**现象**:
|
||
|
||
```csharp
|
||
_scrollRect.content.anchoredPosition +=
|
||
_navInput * (_keyPanSpeed * Time.unscaledDeltaTime);
|
||
```
|
||
|
||
直接修改 `content.anchoredPosition`,绕过了 `ScrollRect` 内部的边界约束(Clamped / Elastic),
|
||
导致按键/摇杆平移时可能将地图内容拖出可视范围边界,且 `ScrollRect.normalizedPosition` 值无法反映真实状态(影响依赖该值的逻辑,如 `CenterOnCurrentRoom`)。
|
||
|
||
**影响**:极端情况下地图内容彻底移出屏幕;CenterOnCurrentRoom 通过 normalizedPosition 居中后,
|
||
若同时有键盘平移输入,两者可能产生冲突抖动。
|
||
|
||
**修复方案**:改为累加到 `ScrollRect.normalizedPosition` 并 `Clamp01`,或使用 `ScrollRect.velocity`(ScrollRect 会内部限制)。
|
||
更简洁的方案:在 `ScrollRect.movementType = Clamped` 时,写 `content.anchoredPosition` 会由 ScrollRect 在下一帧强制 Clamp;但应通过 `SetNormalizedPosition` 做明确的边界安全写入。
|
||
|
||
---
|
||
|
||
## 四、历次修复回顾(R1–R14 确认无倒退)
|
||
|
||
| 轮次 | 关键修复 | 状态 |
|
||
|------|---------|------|
|
||
| R1–R8 | 架构解耦、接口层、ServiceLocator、事件通道 | ✅ |
|
||
| R9–R10 | 对象池、脏标记、编辑器拖拽、Play Mode 叠加 | ✅ |
|
||
| R11 | O(viewRadius²) 空间索引、MapDatabaseSO 双重 O(1) | ✅ |
|
||
| R12 | 3 对象池 MapPanel、RevealAnim、MapPinConfigSO | ✅ |
|
||
| R13 | InputSystem 全迁移、TeleportService 创建、HasCustomExitPos | ✅ |
|
||
| R14 | ISaveable 签名修复、TeleportStation flag、编辑器 GC 零分配 | ✅ |
|
||
|
||
---
|
||
|
||
## 五、修复优先级汇总
|
||
|
||
| 编号 | 严重度 | 文件 | 修复工作量 |
|
||
|------|--------|------|-----------|
|
||
| N1 | High | `MapLayoutEditorWindow.cs` — `DrawRoomBadge` | 5 行 |
|
||
| N2 | Medium | `MapProgressDisplay.cs` — 添加 RegionNameEntry 解析 | 20 行 |
|
||
| N3 | Low | `MapInputHandler.cs` — 改用边界安全写入 | 5 行 |
|
||
|
||
---
|
||
|
||
## 六、Post-fix 预估评分
|
||
|
||
修复 N1 + N2 + N3 后:
|
||
|
||
| 维度 | Post-fix 预估 |
|
||
|------|--------------|
|
||
| 架构设计与解耦 | 19 |
|
||
| 性能优化 | 18 |
|
||
| 编辑器扩展 | 19 (+3) |
|
||
| 功能完整性 | 18 (+1) |
|
||
| 数据模型 | 18 |
|
||
| 代码质量 | 19 (+1) |
|
||
| 可扩展性 | 17 |
|
||
| InputSystem 集成 | 18 |
|
||
| **合计** | **146 / 160 → 91.3 / 100** |
|
||
|
||
> 距满分差距主要来自:①旧兼容 bool 字段(IsBossRoom/IsSavePoint/IsShop)未清理;
|
||
> ②MapPanel/MinimapHUD 缺少开关过渡动画(由 UIManager 层决定,超出本模块范围);
|
||
> ③MapProgressDisplay 无探索进度脏检查(每次事件都完整重算)。
|