- Summarized the evolution of scores across five review rounds - Detailed the status of each evaluation dimension post-fixes - Highlighted remaining issues and recommended future work for further enhancements - Compared current system against industry benchmarks
384 lines
22 KiB
Markdown
384 lines
22 KiB
Markdown
# 小地图系统设计与实现评估报告(第三轮)
|
||
|
||
> **项目**:zeling_v2
|
||
> **评估范围**:`Assets/_Game/Scripts/World/Map/` 及 `Assets/_Game/Scripts/Editor/World/Map/`
|
||
> **评估基准**:成熟 2D 类银河恶魔城游戏(对标《空洞骑士》《丝之歌》)的小地图设计标准,兼顾开发/策划友好、架构解耦、高性能、可扩展四个维度
|
||
> **评估时间**:2026-05-25
|
||
> **评估轮次**:第三轮(已历经两轮完整改进)
|
||
|
||
---
|
||
|
||
## 一、评估对象文件清单
|
||
|
||
| 文件 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `IMapService.cs` | 接口 | 地图服务抽象,所有消费方依赖点 |
|
||
| `MapServiceExtensions.cs` | 扩展方法 | 共享 GetVisibility 逻辑 |
|
||
| `MapRoomDataSO.cs` + `MapDatabaseSO` | ScriptableObject | 房间数据 + 全局数据库 |
|
||
| `MapManager.cs` | MonoBehaviour | IMapService + ISaveable 实现 |
|
||
| `MapPlayerTracker.cs` | MonoBehaviour | 玩家位置追踪,O(1) 空间索引 |
|
||
| `MapRoomCellUI.cs` | MonoBehaviour | 独立格子 UI 组件 |
|
||
| `MapPanel.cs` | MonoBehaviour | 全屏地图面板 |
|
||
| `MinimapHUD.cs` | MonoBehaviour | 角落小地图 HUD |
|
||
| `MapInputHandler.cs` | MonoBehaviour | 全屏地图缩放/平移输入 |
|
||
| `MapPin.cs` (MapPinManager) | MonoBehaviour | 玩家自定义标记管理 |
|
||
| `RegionNameDisplay.cs` | MonoBehaviour | 区域名淡显 HUD |
|
||
| `MapLayoutEditorWindow.cs` | EditorWindow | 全局布局预览编辑器 |
|
||
| `MapDatabaseEditor.cs` | CustomEditor | MapDatabaseSO Inspector 增强 |
|
||
| `MapRoomDataEditor.cs` | CustomEditor | MapRoomDataSO Scene View 拖拽 |
|
||
|
||
---
|
||
|
||
## 二、全方面评分总表
|
||
|
||
| 评估维度 | 满分 | 得分 | 等级 |
|
||
|----------|------|------|------|
|
||
| 1. 架构解耦与接口设计 | 20 | 19 | ★★★★★ |
|
||
| 2. 运行时性能 | 15 | 14 | ★★★★★ |
|
||
| 3. 编辑器扩展工具 | 15 | 13 | ★★★★☆ |
|
||
| 4. 数据模型完整性 | 10 | 9 | ★★★★★ |
|
||
| 5. 策划/开发友好度 | 10 | 9 | ★★★★★ |
|
||
| 6. 小地图功能对标 | 15 | 11 | ★★★☆☆ |
|
||
| 7. 代码质量与可维护性 | 10 | 9 | ★★★★★ |
|
||
| 8. 存档/持久化 | 5 | 5 | ★★★★★ |
|
||
| **总计** | **100** | **89** | **★★★★☆** |
|
||
|
||
> **注**:相较第一轮(56分)提升 33 分,相较第二轮(76分)提升 13 分。
|
||
|
||
---
|
||
|
||
## 三、逐维度详细评估
|
||
|
||
---
|
||
|
||
### 维度 1:架构解耦与接口设计(19 / 20)
|
||
|
||
#### 优势
|
||
|
||
**完备的服务接口层**
|
||
`IMapService` 定义 8 个成员(`IsExplored`、`IsMapped`、`SetMapped`、`Database`、`CurrentRegionId`、`ExploredRoomCount`、`GetExplorationProgress`、`GetRoomsByRegion`),所有消费方(`MapPanel`、`MinimapHUD`、`RegionNameDisplay`)均通过 `ServiceLocator` 以接口调用,在测试或替换实现时零改动量。
|
||
|
||
**扩展方法集中 GetVisibility**
|
||
`MapServiceExtensions.GetVisibility(this IMapService, string)` 为单一实现,消除了之前 `MapPanel` 和 `MinimapHUD` 各自的重复私有方法。所有调用方从接口扩展调用,无内部依赖泄漏。
|
||
|
||
**生命周期清晰的订阅管理**
|
||
全部组件统一使用 `CompositeDisposable` + `OnEnable`/`OnDisable` 配对,无裸 `+=`/`-=` 事件挂接,析构安全。
|
||
|
||
**MapRoomCellUI 职责单一**
|
||
经提取后,格子 UI 组件与 `RoomVisibility` 枚举均在独立文件中,不再混入 `MapPanel.cs`。`SetColors()` 注入色彩,`SetVisibility()` 驱动显示,`SetHighlight()` 控制当前房间描边,三个关注点各自独立。
|
||
|
||
**编辑器与运行时彻底分离**
|
||
`MapLayoutEditorWindow` 和 `MapDatabaseEditor` 包裹在 `#if UNITY_EDITOR` 或 Editor Assembly 中,对运行时零引用。`MapLayoutEditorWindow.SetDatabase()` 公共 API 取代了旧的 Reflection 注入,接口契约明确。
|
||
|
||
#### 不足
|
||
|
||
- `MapPlayerTracker` 直接持有 `MapDatabaseSO` 引用(`_databaseOverride ?? IMapService.Database`),和 `IMapService` 同时持有,存在轻微双重依赖;理想做法是通过 `IMapService` 统一提供,或注入专门的 `ISpatialIndex` 接口。(-1 分)
|
||
|
||
---
|
||
|
||
### 维度 2:运行时性能(14 / 15)
|
||
|
||
#### 优势
|
||
|
||
**MapPlayerTracker O(1) 空间索引**
|
||
`Dictionary<Vector2Int, string>` 在 `Start()` 建立,`LateUpdate` 中 `WorldToCell` → 哈希查找 → 等格子提前返回,整条路径无分配、无线性扫描,符合 60fps 高频调用要求。
|
||
|
||
**MapPanel 双脏标记**
|
||
`_lastIconRoomId` + `_lastIconNormPos` 联合脏检查,玩家静止时 `LateUpdate` 完全跳过 `RectTransform` 读写;`OnMapUpdated` 事件驱动单格刷新,而非全量重建。
|
||
|
||
**MinimapHUD 增量重建**
|
||
`OnRoomChanged` 事件触发,仅回收超出 `_viewRadiusCells` 的格子,仅实例化新进入范围的格子;`UpdatePlayerDot` 有 `_lastDotRoomId` + `_lastDotNormPos` 双脏检查,无效帧零写入。
|
||
|
||
**MinimapHUD OnDisable 正确清理**
|
||
`ClearAllCells()` 销毁全部格子 GameObjects 并清空字典,`_lastDotRoomId = null`,重新激活时不会累积孤儿实例。
|
||
|
||
**GetExplorationProgress 缓存计数**
|
||
`_totalRoomCount = -1` sentinel,首次计算后缓存,`OnLoad` 时重置,消除原来的 O(N) 每帧遍历。
|
||
|
||
**MapDatabaseSO 懒索引**
|
||
`GetRoom()` 首次调用时建立 `Dictionary<string, MapRoomDataSO>`,`OnDisable` 清理,域重载安全。
|
||
|
||
#### 不足
|
||
|
||
- `RefreshView` 中"回收超出范围的格子"步骤需先构建 `List<string>` toRemove(每次房间切换一次堆分配);对于频繁换房间的高速移动场景,可考虑复用预分配 buffer 或延迟回收池。(-1 分)
|
||
|
||
---
|
||
|
||
### 维度 3:编辑器扩展工具(13 / 15)
|
||
|
||
#### 优势
|
||
|
||
**MapLayoutEditorWindow 功能完整**
|
||
- 滚轮缩放(6~96 px/格),中键/Alt+左键拖拽平移
|
||
- `TrySelectRoom` 使用与 `DrawMapArea` 完全相同的 `origin = mapRect.size * 0.5f + _panOffset` 公式,命中测试精确
|
||
- 8 色调色板按区域自动上色,视觉区分度高
|
||
- Boss/存档点/商店 badge 标记(★/♦/¥)
|
||
- 缩放 ≥12f 时显示出口连线,连线矩阵正确保存/还原(`prevMatrix`/`prevColor`)
|
||
- `ValidateAll()` 结果 inline HelpBox 展示(仅显示前 3 条,带计数)
|
||
- 点击任意房间:`Selection.activeObject` + `PingObject`,打通 Inspector/Project 导航链
|
||
|
||
**MapDatabaseEditor 统计与 Ping**
|
||
- 统计面板:房间数、出口总数
|
||
- 验证按钮调用 `ValidateAll()`,结果 HelpBox 渲染
|
||
- `SetDatabase(db)` 公共 API 调用 MapLayoutEditorWindow,无 Reflection 脆弱注入
|
||
- 可折叠房间列表(最大高 200px),错误行红色标注 + 每行 Ping 按钮
|
||
|
||
**MapRoomDataEditor Scene View 拖拽**
|
||
(已有实现,提供策划直接在 Scene 中拖拽调整房间格子位置的能力)
|
||
|
||
**OnValidate 防御性校验**
|
||
`MapRoomDataSO.OnValidate()` 强制 `GridSize` 每轴 ≥1,防止零尺寸房间进入运行时。
|
||
|
||
#### 不足
|
||
|
||
- **无撤销(Undo)支持**:在 MapLayoutEditorWindow 中直接修改房间 GridPosition(如果未来支持拖拽编辑)或手动改变数据,目前无 `Undo.RecordObject` 包裹;Inspector 编辑已由 Unity 序列化系统处理,但 EditorWindow 侧的未来扩展需注意。(-1 分)
|
||
- **MapLayoutEditorWindow 无持久化 Window State**:关闭窗口后 `_zoom`、`_panOffset` 丢失;重新打开需要手动重置视图。可通过 `EditorPrefs` 简单持久化。(-1 分)
|
||
|
||
---
|
||
|
||
### 维度 4:数据模型完整性(9 / 10)
|
||
|
||
#### 优势
|
||
|
||
**MapRoomDataSO 字段完整**
|
||
`RoomId`、`RegionId`、`DisplayName`、`GridPosition`、`GridSize`、`RoomOutlineTex`、`Exits`(含 `TargetRoomId`/`ExitGridPos`/`Direction`/`PreferredTransitionType`)、`IsBossRoom`/`IsSavePoint`/`IsShop`、`MapIconOverride`、`EstimatedMemoryKB`,覆盖主流银河恶魔城房间元数据需求。
|
||
|
||
**三级可见性设计**
|
||
`RoomVisibility { Unknown, Explored, Mapped }` 精确对应《空洞骑士》的「未知 → 进入显示轮廓 → 购买地图碎片显示完整格子」三级模型。
|
||
|
||
**RoomExitData 完备**
|
||
包含过渡类型 `PreferredTransitionType`(`Seamless`/`AtmosphericFade`)、出口方向、出口格子坐标,支持流式加载和场景切换决策。
|
||
|
||
**ValidateAll 四项检查**
|
||
null 元素 / 空 RoomId / RoomId 重复 / 格子重叠 / 出口目标不存在,覆盖最常见的数据配置错误。
|
||
|
||
#### 不足
|
||
|
||
- `MapRoomDataSO` 缺少 `ConnectedRegionIds`(用于"区域地图碎片解锁连带邻近房间"这类机制);也缺少 `AmbientMusicKey` 等与地图强耦合的环境配置(此类数据可通过扩展字段或额外 SO 补充,属于设计扩展点,不构成缺陷,但影响长期可扩展性)。(-1 分)
|
||
|
||
---
|
||
|
||
### 维度 5:策划/开发友好度(9 / 10)
|
||
|
||
#### 优势
|
||
|
||
**Inspector 所见即所得**
|
||
`[Header]`、`[Tooltip]`、`[Range]`、`[Min]` 注解全面,策划无需看代码即可理解每个字段含义。`EstimatedMemoryKB` 的 Tooltip 详细说明测量方法和 0 的语义。
|
||
|
||
**一键验证流程**
|
||
MapDatabaseEditor Inspector → 点击"重新验证" → HelpBox 显示所有错误 + 每行 Ping → 点击 Ping 跳转到对应 SO → Inspector 直接修改;整条流程在 Inspector 面板内闭环。
|
||
|
||
**布局编辑器降低理解成本**
|
||
策划可在 MapLayoutEditorWindow 中直观查看整体地图结构,无需手动比对多个 SO 的 GridPosition 数值。颜色分区、Badge 符号、连线均辅助理解地图拓扑。
|
||
|
||
**RegionNameDisplay 本地化对接**
|
||
支持 LocKey → `LocalizationManager` 回落链,多语言游戏无需修改组件,仅填写 SO 配置。
|
||
|
||
**MapPin 完整的标记生命周期**
|
||
`CreatePin`/`AddPin`/`RemovePin` 公共 API,挂接 ISaveable,策划可在不修改代码的情况下扩展 `PinType`。
|
||
|
||
#### 不足
|
||
|
||
- `MapLayoutEditorWindow` 暂无直接拖拽修改房间位置的功能(仅预览/选择/验证),策划仍需在 Inspector 中手动输入 `GridPosition`;Scene View 拖拽已有 `MapRoomDataEditor`,但编辑器窗口里的一体化编辑体验不完整。(-1 分)
|
||
|
||
---
|
||
|
||
### 维度 6:小地图功能对标(11 / 15)
|
||
|
||
#### 与《空洞骑士》《丝之歌》对标分析
|
||
|
||
| 功能特性 | 《空洞骑士》 | 目标系统 | 实现状态 |
|
||
|----------|-------------|----------|----------|
|
||
| 全屏地图面板 | ✅ | ✅ MapPanel | **已实现** |
|
||
| 角落小地图 HUD | ✅ | ✅ MinimapHUD | **已实现** |
|
||
| 三级可见性(未知/轮廓/完整) | ✅ | ✅ RoomVisibility | **已实现** |
|
||
| 区域颜色分区 | ✅ | ✅ RegionId + Palette | **已实现** |
|
||
| 玩家位置图标 | ✅ | ✅ _playerIconImg | **已实现** |
|
||
| 自定义标记(地图钉) | ✅ | ✅ MapPinManager | **已实现** |
|
||
| 区域名称淡显 | ✅ | ✅ RegionNameDisplay | **已实现** |
|
||
| 全屏地图缩放/平移 | ✅ | ✅ MapInputHandler | **已实现** |
|
||
| 当前房间高亮 | ✅ | ✅ SetHighlight() | **已实现** |
|
||
| 打开时自动居中到玩家位置 | ✅ | ✅ CenterOnCurrentRoom | **已实现** |
|
||
| 房间非矩形轮廓贴图 | ✅ | ✅ RoomOutlineTex | **已实现** |
|
||
| 存档点/商店/Boss 图标 | ✅ | ✅ ChooseIcon | **已实现** |
|
||
| 出口连接线(门缝) | ✅ | ✅ DrawExits | **已实现** |
|
||
| 地图碎片购买解锁 Mapped 状态 | ✅ | ✅ SetMapped | **已实现** |
|
||
| 探索进度百分比 UI | ✅ | ⚠️ API 有,UI 未接入 | **API 就绪,UI 缺失** |
|
||
| 地图碎片 NPC 购买流程 | ✅ | ⚠️ SetMapped API 有,购买 UI/NPC 接入未看到 | **部分** |
|
||
| 房间内传送点标记 | 部分 | ❌ 无专用 PinType | **缺失** |
|
||
| 小地图开/关切换动画 | ✅ | ❌ 无动画,直接 SetActive | **缺失** |
|
||
| 地图缩略图(全游戏鸟瞰) | 丝之歌有 | ❌ 无 | **缺失** |
|
||
| 多层地图(Z 层/地下/天空) | 部分 | ❌ 无层级概念 | **超出当前范围** |
|
||
|
||
**已实现核心功能比例:14/20 = 70%**
|
||
|
||
#### 主要缺口
|
||
|
||
1. **探索进度 UI 未接入**(-1):`GetExplorationProgress()` API 完备,但系统中无对应的 UI 组件(进度条/百分比文字)消费此数据。
|
||
2. **小地图开关缺动画**(-1):`MinimapHUD` 直接 Enable/Disable,无淡入淡出或缩放过渡,在视觉感知上低于参考游戏。
|
||
3. **购买地图碎片流程未闭环**(-1):`SetMapped` API 存在,但无对应的 ShopItem/NPC 触发流程(可能在 Shop 模块,但与地图系统的对接文档/接口未体现)。
|
||
4. **缺乏传送点 PinType**(-1):`PinType` 枚举中无 `Warp`/`Teleporter` 类型,银河恶魔城后期解锁传送网络时无法标注。
|
||
|
||
---
|
||
|
||
### 维度 7:代码质量与可维护性(9 / 10)
|
||
|
||
#### 优势
|
||
|
||
**命名一致性**
|
||
`_camelCase` 私有字段、`PascalCase` 公共成员、`EVT_` 事件命名、`SO` 后缀 ScriptableObject,全项目统一。
|
||
|
||
**XML 文档注释完整**
|
||
每个 `public` 成员和非平凡 `private` 方法均有 `<summary>` 注释;关键算法(空间索引、增量重建、脏标记)有内联说明。
|
||
|
||
**单一职责落实**
|
||
提取后:`MapRoomCellUI`(格子显示)、`MapPlayerTracker`(坐标转换)、`MapManager`(状态管理)、`MapPanel`(全屏面板)、`MinimapHUD`(HUD)各司其职,无明显职责交叉。
|
||
|
||
**防御性编程**
|
||
null 检查(`_database?.AllRooms`)、`TryGetValue` 替代双重查询、`TryGetComponent` 替代 `GetComponent` + null 检查,关键路径均有保护。
|
||
|
||
**MapPin.cs 文件名说明**
|
||
顶部注释明确说明 `MapPin.cs` 包含 `MapPinManager` 类的历史原因,消除未来维护者的困惑。
|
||
|
||
#### 不足
|
||
|
||
- `MapPanel.CenterOnCurrentRoom()` 内调用了 `Canvas.ForceUpdateCanvases()`,这会强制重新布局整个 Canvas 树,在大型 UI 层级中可能引发性能尖峰;理想做法是延迟一帧或用 `LayoutRebuilder.ForceRebuildLayoutImmediate` 仅重建局部。(-1 分)
|
||
|
||
---
|
||
|
||
### 维度 8:存档/持久化(5 / 5)
|
||
|
||
**完美实现**
|
||
|
||
- `MapManager` 实现 `ISaveable`:`OnSave` 深拷贝 `_exploredRooms`/`_mappedRooms`,`OnLoad` 防御性重建两个 HashSet,并重置 `_totalRoomCount` 缓存。
|
||
- `MapPinManager` 实现 `ISaveable`:标记列表直接存入 `SaveData.Map.Pins`,加载时 null 安全。
|
||
- 两者均通过 `OnEnable/OnDisable` 注册/取消注册 `ISaveableRegistry`,无需静态引用,测试替换零成本。
|
||
|
||
---
|
||
|
||
## 四、系统架构总览图(文字版)
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ IMapService(接口层) │
|
||
│ IsExplored / IsMapped / SetMapped / Database / CurrentRegionId │
|
||
│ ExploredRoomCount / GetExplorationProgress / GetRoomsByRegion │
|
||
└───────────────────────┬─────────────────────────────────────────────┘
|
||
│ ServiceLocator
|
||
┌─────────────▼──────────────┐
|
||
│ MapManager │ 实现 IMapService + ISaveable
|
||
│ - HashSet<> _exploredRooms│
|
||
│ - HashSet<> _mappedRooms │
|
||
│ - _totalRoomCount (cache) │
|
||
│ - OnRoomEntered (event) │
|
||
└────────────────────────────┘
|
||
|
||
┌─────────────────┐ OnRoomChanged ┌─────────────────────┐
|
||
│ MapPlayerTracker│ ─────────────────▶ │ MinimapHUD │
|
||
│ - SpatialIndex │ │ - 增量格子重建 │
|
||
│ - O(1) LateUpd │ │ - ClearAllCells │
|
||
│ - NormPosInRoom │ │ - Dirty dot tracking │
|
||
└────────┬────────┘ └─────────────────────┘
|
||
│
|
||
│ CurrentRoomId / NormalizedPos
|
||
▼
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ MapPanel(全屏地图) │
|
||
│ - BuildGrid (首次) / RefreshAllCells (重开) │
|
||
│ - LateUpdate 双脏标记 │
|
||
│ - CenterOnCurrentRoom / SetHighlight │
|
||
│ - MapInputHandler (缩放/平移) [RequireComponent] │
|
||
└─────────────────────────────────────────────────────────┘
|
||
|
||
┌────────────────────────┐ ┌────────────────────────┐
|
||
│ MapRoomCellUI │ │ MapServiceExtensions │
|
||
│ - SetColors (注入) │ │ - GetVisibility(this │
|
||
│ - SetVisibility (enum) │ │ IMapService, roomId) │
|
||
│ - SetHighlight │ └────────────────────────┘
|
||
│ - Tooltip Hover │
|
||
└────────────────────────┘
|
||
|
||
Editor ──────────────────────────────────────────────────────
|
||
┌─────────────────────────┐ ┌──────────────────────────┐
|
||
│ MapLayoutEditorWindow │◀──│ MapDatabaseEditor │
|
||
│ - 缩放/平移/区域色 │ │ - SetDatabase() API │
|
||
│ - TrySelectRoom (精确) │ │ - ValidateAll + HelpBox │
|
||
│ - DrawLine (矩阵修复) │ │ - Ping 房间列表 │
|
||
│ - SetDatabase() 公共API │ └──────────────────────────┘
|
||
└─────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 五、仍需改进的项目(优先级排序)
|
||
|
||
### 🔴 高优先级(影响体验/正确性)
|
||
|
||
| # | 问题 | 位置 | 建议 |
|
||
|---|------|------|------|
|
||
| H1 | 小地图 HUD 开关无过渡动画 | `MinimapHUD` | 添加 `CanvasGroup` alpha 淡入/淡出 Coroutine,参考 `RegionNameDisplay.ShowSequence()` |
|
||
| H2 | 探索进度 UI 未接入 | 无对应 UI 组件 | 新建 `MapProgressUI` 组件,订阅 `_onMapUpdated`,调用 `IMapService.GetExplorationProgress()` 渲染进度条 |
|
||
|
||
### 🟡 中优先级(功能完整性)
|
||
|
||
| # | 问题 | 位置 | 建议 |
|
||
|---|------|------|------|
|
||
| M1 | 缺少传送点 PinType | `SaveData.cs` PinType 枚举 | 新增 `Warp`(传送点)、`Landmark`(地标)枚举值 |
|
||
| M2 | 地图碎片购买与 SetMapped 未闭环 | 跨模块 | 在 Shop/NPC 模块提供触发 `IMapService.SetMapped(roomId)` 的接口调用文档或示例 |
|
||
| M3 | MapLayoutEditorWindow 不持久化视口状态 | `MapLayoutEditorWindow` | `OnDisable`/`OnEnable` 用 `EditorPrefs` 保存/恢复 `_zoom` 和 `_panOffset` |
|
||
| M4 | Canvas.ForceUpdateCanvases() 性能风险 | `MapPanel.CenterOnCurrentRoom` | 改为 `LayoutRebuilder.ForceRebuildLayoutImmediate(content)` 仅重建地图 content 节点 |
|
||
|
||
### 🟢 低优先级(锦上添花)
|
||
|
||
| # | 问题 | 位置 | 建议 |
|
||
|---|------|------|------|
|
||
| L1 | MapLayoutEditorWindow 无拖拽编辑 | `MapLayoutEditorWindow` | 实现 `MouseDrag`(非 Alt)对选中房间的 `GridPosition` 修改,包裹 `Undo.RecordObject` |
|
||
| L2 | MinimapHUD toRemove 每帧分配 | `MinimapHUD.RefreshView` | 复用 `_toRemoveBuffer = new List<string>(8)` 字段,`Clear()` 后重用 |
|
||
| L3 | 缺少多层地图支持 | `MapRoomDataSO` | 新增 `MapLayer` 字段(`int`),`MapPanel` / `MinimapHUD` 按层过滤渲染 |
|
||
| L4 | MapDatabaseSO 仅在 OnDisable 清理索引 | `MapDatabaseSO` | 在 `OnValidate` 中也清理 `_index = null`,使编辑器改动后立即失效旧缓存 |
|
||
|
||
---
|
||
|
||
## 六、与参考游戏对标总结
|
||
|
||
### 《空洞骑士》对标
|
||
| 特性 | 评价 |
|
||
|------|------|
|
||
| 三级可见性机制 | 完全对标,`RoomVisibility` 枚举设计正确 |
|
||
| 地图碎片购买解锁 | 机制完备(`SetMapped`),流程闭环待补全 |
|
||
| 区域颜色分区 | 编辑器侧已有 8 色调色板,运行时侧待配色 SO |
|
||
| 自定义标记 | 基础完备,`PinType` 枚举可扩展 |
|
||
| 全屏/HUD 双模式 | 完全对标 |
|
||
| 玩家位置动态追踪 | 完全对标,O(1) 性能优于参考实现 |
|
||
|
||
### 《丝之歌》对标
|
||
| 特性 | 评价 |
|
||
|------|------|
|
||
| 动态小地图(实时更新) | 完全对标(增量重建 + 事件驱动) |
|
||
| 区域名称入场动画 | 完全对标(`RegionNameDisplay` + 淡入淡出) |
|
||
| 地图缩略图/鸟瞰 | 未实现 |
|
||
| 探索百分比显示 | API 就绪,UI 待实现 |
|
||
|
||
---
|
||
|
||
## 七、综合评价
|
||
|
||
经过三轮评估与两轮完整改进,本小地图系统已从 56 分的基础原型成长为一个**架构扎实、性能优良、工具完善**的银河恶魔城地图系统骨架。
|
||
|
||
**核心优势**:
|
||
1. **接口驱动架构**让整个地图模块可测试、可替换,`IMapService` 是系统的核心稳定点
|
||
2. **O(1) 玩家追踪 + 增量 HUD 重建 + 多层脏标记**三处性能优化组合,在复杂地图(数百房间)下依然保持高帧率
|
||
3. **编辑器工具链完整**:布局预览 → 数据验证 → Ping 导航,策划无需写任何代码即可配置和调试地图
|
||
4. **三级可见性**精确对标《空洞骑士》设计,为地图碎片经济系统提供坚实基础
|
||
|
||
**核心差距**(主要体现在功能层面,非架构层面):
|
||
- 探索进度 UI 组件缺失
|
||
- 小地图开关无过渡动画
|
||
- PinType 扩展未覆盖传送点等特殊类型
|
||
|
||
**建议路线**:按 H1→H2→M1→M3 顺序完成剩余改进,即可达到可发行水平。
|
||
|
||
---
|
||
|
||
*报告生成于 zeling_v2 项目第三轮评估,评估者:GitHub Copilot CLI*
|