Files
zeling_v2/Docs/Review/Minimap_Review_Round6_Independent.md
T
joywayer e2bc324905 Add independent review report for Minimap system Round 7
- Validate fixes from Round 6 and identify new issues
- Document findings including UX defects, editor integration flaws, and code quality concerns
- Propose solutions and prioritize issues based on severity
- Evaluate against standards of mature 2D Metroidvania games
2026-05-25 14:44:31 +08:00

25 KiB
Raw Blame History

小地图系统 Round 6 独立评估报告

评估日期Round 6(基于当前代码状态)
评估方法:独立从零阅读所有 14 个地图模块文件,不参考 Round 5 自评结论
对标标准:成熟 2D Metroidvania 游戏小地图,专注编辑器扩展质量、架构解耦、高性能、策划友好度
注意:本轮评估目标是发现 Round 5 自评可能存在的通胀,以及 Round 4 修复后遗留的真实问题


一、所有评估文件清单

文件 类型
IMapService.cs 运行时接口
IPlayerPositionProvider.cs 运行时接口(新)
IPinService.cs 运行时接口(新)
MapGridConstants.cs 运行时常量(新)
MapServiceExtensions.cs 运行时扩展方法
MapRoomDataSO.cs + MapDatabaseSO 数据层 SO
MapManager.cs 运行时管理器
MapPlayerTracker.cs 运行时玩家追踪
MapPin.csMapPinManager 运行时标记管理
MapRoomCellUI.cs 运行时 UI 格子
MapPanel.cs 运行时全屏地图
MinimapHUD.cs 运行时小地图 HUD
MapInputHandler.cs 运行时输入处理
RegionNameDisplay.cs 运行时区域名显示
MapRoomDataEditor.cs 编辑器扩展
MapDatabaseEditor.cs 编辑器扩展
MapLayoutEditorWindow.cs 编辑器扩展

二、逐维度独立评分

维度 1:架构解耦(Architecture Decoupling

优点

接口三层完整:

IMapService            ← ServiceLocator ← MapManager (ISaveable)
IPlayerPositionProvider ← ServiceLocator ← MapPlayerTracker
IPinService            ← ServiceLocator ← MapPinManager (ISaveable)
  • MapPanelMinimapHUD 零具体类 SerializeField 引用,仅通过接口消费 ✓
  • ServiceLocator 注册/注销生命周期管理正确:
    • MapManager: Awake 注册,单例保护,OnDestroy 注销 ✓
    • MapPlayerTracker: Awake 注册(带 GetOrDefault 保护),OnDestroy 注销 ✓
    • MapPinManager: OnEnable/OnDisable 注册/注销,与 ISaveableRegistry 同步 ✓
  • MapServiceExtensions.GetVisibility() 将三级状态推导逻辑集中在一处,消费方零重复 ✓
  • OnDisable 时清空所有接口引用,避免悬挂引用 ✓

⚠️ 问题

  1. MapDatabaseSO 双重职责:既是数据容器(AllRooms[])又是服务类(GetRoom()ValidateAll())。ValidateAll 是 O(N²) 操作且只应在编辑器调用,但它存在于运行时 SO 中——缺少 #if UNITY_EDITOR 保护或独立的验证服务类。
  2. MapRoomDataSOMapDatabaseSO 同文件:Unity 约定每个 SO 类独立一个文件,同文件降低可发现性。
  3. IMapService.Database 属性暴露了具体类型 MapDatabaseSO:接口直接暴露具体 SO 类,消费方(MinimapHUD、MapPanel)均直接访问 Database.AllRooms,若未来替换数据源需修改接口。

评分:9/10(接口体系完整,主要扣分点:Database 属性暴露具体类,ValidateAll 无编辑器保护)


维度 2:性能(Performance

已解决的热路径

问题 解决方案
NormalizedPositionInRoom 离散跳动 世界坐标精确插值
Canvas.ForceUpdateCanvases() 全树刷新 LayoutRebuilder.ForceRebuildLayoutImmediate(content) 局部
Pin 重绘无脏检查 _lastPinVersion dirty check
GetPinSprite O(N) 循环 Dictionary<PinType, Sprite> O(1) 查找
MapPlayerTracker 每帧 GetRoom 查找 _currentRoom 缓存
LateUpdate 每帧写 RectTransform dirty check(位置 + 房间 ID 双重检查)
MinimapHUD _toRemove 每次分配 字段复用
GUIStyle 每帧每格创建 EnsureLabelStyles() 带缩放变化检测

⚠️ 遗留性能问题

P1(真实瓶颈):MinimapHUD.RefreshView O(N) 遍历

// MinimapHUD.cs 第137行
foreach (var room in db.AllRooms)  // O(N) 遍历全部房间
{
    if (room == null || _cells.ContainsKey(room.RoomId)) continue;
    if (!RoomInView(room, minX, maxX, minY, maxY)) continue;
    ...
}

每次房间切换(OnRoomChanged)遍历 db.AllRooms 全量扫描。房间数 ≤ 50 时影响不大,100+ 房间时每次切换房间触发 O(N) 遍历。正确做法应为空间分区(Dictionary<Vector2Int, string>)。

P2(编辑器):MapDatabaseEditor 错误行样式每帧分配

// MapDatabaseEditor.cs 第125-127行
var rowStyle = hasError
    ? new GUIStyle(EditorStyles.label) { normal = { textColor = new Color(1f, 0.35f, 0.35f) } }
    : EditorStyles.label;

每次 OnInspectorGUI 重绘(高频)为每个错误房间分配新 GUIStyle,应缓存为字段(类比 MapLayoutEditorWindow_roomLabelStyle 做法)。

P3(低频):GetRoomsByRegion 每次 LINQ + ToArray 分配

return _database.AllRooms.Where(r => r != null && r.RegionId == regionId).ToArray();

调用频率低,但每次调用均堆分配新数组,可改为返回 IReadOnlyList<T> + 缓存或仅在热路径上注意。

评分:8/10(热路径整体优化良好,MinimapHUD O(N) 遍历是真实未修复问题,编辑器 GUIStyle 分配)


维度 3:编辑器扩展质量(Editor Extension Quality

优点

MapRoomDataEditorSceneView 拖拽)

  • 双角控制点 BL/TR,精度 1 格 ✓
  • Undo.RecordObject 支持撤销 ✓
  • 防反转保护(Mathf.Min/Max
  • 一键居中 SceneView ✓
  • 房间 ID 标签 + 颜色可读 ✓

MapDatabaseEditorInspector 增强)

  • 统计摘要(房间数、出口总数) ✓
  • 一键验证 + HelpBox 错误列表 ✓
  • _cachedErrorRoomIds 仅按钮点击时重建,避免高频 GC ✓
  • 引号精确匹配("'{r.RoomId}'" 防前缀误判) ✓
  • 一键打开布局编辑器 + SetDatabase() 公共 API ✓
  • 可折叠房间列表 + Ping ✓

MapLayoutEditorWindow(独立窗口)

  • 全局地图实时预览 ✓
  • 滚轮缩放 + 中键/Alt拖拽平移 ✓
  • 区域自动配色(8 色方案) ✓
  • 验证错误红色高亮 ✓
  • 点击选中房间 → Selection + Ping ✓
  • 出口连线(_zoom >= 12f 时显示) ✓
  • GUIStyle 缓存(EnsureLabelStyleszoom 变化时重建) ✓

⚠️ 问题

  1. MapDatabaseEditor 错误行样式未缓存(同 P2,编辑器性能问题,见上文)
  2. Undo.undoRedoPerformed 回调:在 MapRoomDataEditor 中通过 SceneView 拖拽修改后,执行 Ctrl+Z 撤销,MapLayoutEditorWindow 不会自动刷新视图,需手动点击 Repaint。
  3. 无批量房间创建向导:策划需逐个手动创建 MapRoomDataSO.asset,缺少"从场景列表批量生成"工具。
  4. MapRoomDataEditor.CELL_SIZE 硬编码为 1fSceneView 控制点坐标基于 1 格 = 1 世界单位。如果关卡实际比例不同(MapPlayerTracker._worldUnitsPerCell = 18f),SceneView 中的可视化与实际地图 UI 比例不一致,容易混淆策划。

评分:8.5/10(三工具功能完整,主要缺口:Undo 回调刷新、批量创建向导、SceneView 与 UI 比例不一致的隐患)


维度 4:数据设计(Data Design

优点

  • MapRoomDataSO 字段语义完整:基础信息、格子坐标、轮廓纹理、出口数据、特殊标记、流式加载内存预估 ✓
  • RoomExitData.PreferredTransitionType:区分 Seamless/AtmosphericFade,过渡类型枚举化 ✓
  • MapDatabaseSO.GetRoom() 懒加载索引 + OnValidate/OnDisable 缓存清理 ✓
  • 四类验证覆盖:null、RoomId 重复、格子重叠、出口悬空 ✓
  • MapRoomDataSO.OnValidate 保护 GridSize 最小值 ✓
  • PinSpriteEntry 移入 MapPin.cs,数据与逻辑同文件 ✓

⚠️ 问题

  1. 无 RegionSO 数据资产RegionIdstring,区域的颜色主题、显示名、排序等属性无处集中配置,目前散落在:
    • RegionNameDisplay._regionNames(运行时组件)
    • MapLayoutEditorWindow.Palette(编辑器,按发现顺序自动分配,不可控)
  2. ValidateAll 仅单向出口验证:验证 A→B 存在,但不验证 B→A 是否存在(非双向可能是有意设计,但应有注释说明)。
  3. RoomId 与场景名一致约定无自动验证:注释中要求 RoomId 与场景名一致("Room_Forest_01"),但验证逻辑中不检查此约束。
  4. ExitGridPos 未验证是否在房间边界上:出口坐标可以配置在房间内部或完全不相关的位置,验证工具不检测此异常。

评分:8/10(数据设计扎实,主要缺口:缺少 RegionSO、出口验证不够严格)


维度 5:功能完整性(Feature Completeness

已实现功能矩阵

功能 状态
三级可见性(Unknown/Explored/Mapped 完整
存档持久化(探索状态 + 标记) 完整
全屏地图面板 + ScrollRect 完整
角落小地图 HUD 完整
玩家位置图标(平滑跟随) 完整
当前房间高亮描边 完整
自定义标记 Pin 完整
出口连接线显示 完整
鼠标滚轮 + 键盘平移缩放 完整
区域变化广播 + 区域名渐显动画 完整
房间 TooltipDisplayName 完整
MapFragment 购买揭示(SetMapped 接口完整
探索进度 API 接口完整
非矩形房间轮廓纹理 字段完整(UI 已接入)

缺失/待完善功能

  1. 探索进度无 HUD 显示IMapService.GetExplorationProgress() + ExploredRoomCount 已实现,但 UI 层(MapPanel、MinimapHUD)均未显示进度条或百分比文本。
  2. 移动端 / 手柄支持MapInputHandler 使用旧版 Input.GetAxisRaw,无 Pinch 缩放手势,移动端不可用。
  3. 小地图运行时缩放调节MinimapHUD 的 _cellPixels 只可在 Inspector 配置,玩家运行时无法调整小地图大小(无障碍缺口)。
  4. 标记类型不足Pin 只有基础 PinType 枚举(定义在 SaveData.cs),缺少游戏中常见的「未解谜」「隐藏通道」「收藏品」等语义标记类型的默认配置。
  5. 全屏地图与小地图无联动隐藏:打开全屏地图时 MinimapHUD 不自动隐藏,视觉上有重叠(需外部 UIManager 处理,系统内无协调机制)。

评分:8/10(核心功能覆盖全面,缺失点为进度显示、移动端支持、小地图缩放)


维度 6:代码质量(Code Quality

优点

  • 命名规范一致:_camelCase 私有字段,PascalCase 公有成员 ✓
  • XML 文档注释覆盖所有公共 API ✓
  • //── 区域注释辅助导航 ✓
  • no-game-references 规则完全遵守 ✓
  • MapServiceExtensions 消除消费方重复的三级状态判断逻辑 ✓
  • MapGridConstants.FullMapCellPixels 消除 3 处散落的 32f 硬编码 ✓
  • CompositeDisposable _subs 统一管理事件订阅生命周期 ✓

⚠️ 问题

  1. MapPin.cs 文件名与类名不一致:文件包含 MapPinManager 类,文件头虽有注释说明,但工具搜索"MapPin.cs"不会找到 MapPinManager。这是历史遗留问题,需在安全时机重命名。
  2. MapDatabaseEditor 错误行样式每帧分配(同 P2):
    var rowStyle = hasError
        ? new GUIStyle(EditorStyles.label) { ... }  // ← 每次 OnInspectorGUI 分配
        : EditorStyles.label;
    
  3. MapManager.GetRoomsByRegion 每次 LINQ + ToArray:返回 MapRoomDataSO[],调用方每次得到新数组。建议改为按需缓存或返回 IReadOnlyList<T>
  4. MapPanel.DrawExits 中的硬编码尺寸
    conn.rectTransform.sizeDelta = vertical ? new Vector2(16f, 8f) : new Vector2(8f, 16f);
    
    出口连接线尺寸硬编码为 16f/8f,未使用 MapGridConstants 派生,与全屏地图的格子尺寸(32f)比例关系不透明。
  5. RegionNameDisplay.ResolveDisplayName O(N) 线性查找:区域数量通常 < 20,影响微小,但与 GetPinSprite 字典化处理的一致性不足。

评分:8.5/10(整体规范高,主要扣分点:文件名不一致、MapDatabaseEditor GUIStyle 分配、DrawExits 硬编码)


维度 7:可扩展性(Extensibility

优点

  • 接口层允许替换实现(测试时可 Mock IMapService
  • PinType 枚举可在 SaveData.cs 扩展 + _pinSprites Inspector 配置 ✓
  • 颜色完全可配置(SerializeField on MapPanel, MinimapHUD
  • 事件渠道(EventChannelSO)允许外部任意系统订阅地图事件 ✓
  • MapRoomDataSO SO 驱动,增加房间只需新建资产 ✓
  • MapServiceExtensions 扩展方法机制允许在不修改接口的情况下添加新查询 ✓

⚠️ 问题

  1. MapPanel 无覆盖层(Overlay)扩展点:添加「区域边界覆盖」「探索热度图」等新层需要直接修改 MapPanel.cs,无法通过组件/插件扩展。
  2. MapRoomDataSO 无自定义扩展字段:新增房间属性(如「危险等级」「推荐等级要求」)需修改 SO 类,无法通过 ScriptableObject 继承或 payload 扩展。
  3. IMapService.Database 返回具体类:(同架构问题)限制了未来数据源替换(如从服务器加载、动态生成)的可能性。

评分:8/10(接口 + 事件体系支持良好扩展,主要缺口:MapPanel 无 Overlay 系统,MapRoomDataSO 无扩展字段)


维度 8:策划友好度(Designer/Planner Friendliness

优点

  • MapRoomDataSO 字段有中文 Header + 详细 TooltipEstimatedMemoryKBPreferredTransitionType 均有使用说明)✓
  • MapDatabaseEditor 提供统计摘要、一键验证、可折叠房间列表 ✓
  • MapRoomDataEditor 支持 SceneView 直接拖拽调整房间位置和大小 ✓
  • MapLayoutEditorWindow 直观预览全局地图 + 区域配色区分 ✓
  • 验证错误以 HelpBox/红色高亮明确指出有问题的房间 ✓

⚠️ 问题

  1. 无 MapDesignSpec 文档:缺少指导策划配置地图的设计规范文档(Docs/Standards/MapDesignSpec.md),策划需从代码注释推断配置规则。
  2. 无批量房间创建向导:每个房间需单独创建 SO 并手动填写 RoomId,100 个房间需重复 100 次相同操作。
  3. MapLayoutEditorWindow 无探索状态预览:窗口只显示房间布局,无法预览各可见性状态(Unknown/Explored/Mapped)下的视觉效果。
  4. RegionId 无枚举约束:策划可以在不同 SO 中输入 "Forest""forest" 导致区域不匹配,缺少下拉选择或自动补全。

评分:8/10(工具覆盖主要流程,策划可独立使用,主要缺口:缺乏文档、批量工具、RegionId 输入约束)


三、与 Round 5 自评对比

维度 Round 5 自评 Round 6 独立评分 差值 主要差异
架构解耦 9.5/10 9/10 -0.5 Database 属性暴露具体类型
性能 9/10 8/10 -1 MinimapHUD O(N)遍历未修复
编辑器扩展 9/10 8.5/10 -0.5 无 Undo 刷新回调,GUIStyle 分配
数据设计 8.5/10 8/10 -0.5 缺 RegionSO,出口单向验证
功能完整性 8/10 8/10 0 一致
代码质量 8.5/10 8.5/10 0 一致
可扩展性 8/10 8/10 0 一致
策划友好度 8/10 8/10 0 一致
加权总分 90/100 85/100 -5

Round 5 总分通胀约 +5 分,来源:性能维度对 MinimapHUD 问题评估过松(标注为已知但仍给 9 分),以及架构维度未扣 Database 暴露具体类分。


四、Round 6 发现的新问题(Round 5 未标注)

🔴 N1MapDatabaseEditor 错误行 GUIStyle 每帧分配

位置MapDatabaseEditor.cs 第 125-127 行

var rowStyle = hasError
    ? new GUIStyle(EditorStyles.label) { normal = { textColor = new Color(1f, 0.35f, 0.35f) } }
    : EditorStyles.label;

问题OnInspectorGUI 每次重绘(约 10-30 fps)为每个错误房间分配新 GUIStyleMapLayoutEditorWindow 已通过 EnsureLabelStyles() 正确缓存,但 MapDatabaseEditor 遗漏了相同处理。

修复方案

// 在类中添加缓存字段
private GUIStyle _errorRowStyle;

// 在 OnEnable 或首次使用时初始化
private GUIStyle GetErrorRowStyle()
{
    if (_errorRowStyle == null)
        _errorRowStyle = new GUIStyle(EditorStyles.label) { normal = { textColor = new Color(1f, 0.35f, 0.35f) } };
    return _errorRowStyle;
}

// 使用时
var rowStyle = hasError ? GetErrorRowStyle() : EditorStyles.label;

🔴 N2MapRoomDataEditor.CELL_SIZE 与 MapPlayerTracker._worldUnitsPerCell 比例不一致隐患

位置MapRoomDataEditor.cs 第 16 行 vs MapPlayerTracker.cs 第 25 行

// MapRoomDataEditor.cs
private const float CELL_SIZE = 1f;  // SceneView 中每格 = 1 世界单位

// MapPlayerTracker.cs
[SerializeField] private float _worldUnitsPerCell = 18f;  // 运行时每格 = 18 世界单位

问题

  • SceneView 中拖拽房间角点的坐标系使用 1 格 = 1 世界单位
  • 运行时玩家追踪的坐标系使用 1 格 = 18 世界单位
  • 两套坐标系并存,策划在 SceneView 中看到的房间布局与实际游戏世界坐标无直接对应关系
  • 若策划以为 SceneView 中调整的就是游戏内的实际空间,会在关卡设计时产生误解

建议:在 MapRoomDataEditor 的 SceneView HelpBox 中明确说明此坐标换算,或将 CELL_SIZEMapGridConstants 派生(需将 CELL_SIZE 添加到常量类)。


🟡 N3MinimapHUD.RefreshView 中 db.AllRooms 遍历顺序不稳定问题

RefreshView 先回收旧格子,再添加新格子时:

// 步骤③:重定位全部格子(含新加入的)
foreach (var (id, cell) in _cells)
{
    if (cell == null) continue;
    var r = db.GetRoom(id);   // ← 每次 GetRoom 触发索引查找,O(1) 但有 dict 访问开销
    if (r != null) PlaceCell(cell, r);
}

在步骤②已经通过 cell.Setup() 设置了格子位置(基于 MapGridConstants.FullMapCellPixels),步骤③立即通过 PlaceCell_cellPixels 覆盖。这意味着 Setup() 的位置设置对 MinimapHUD 完全无效,每次都被 PlaceCell 覆盖,产生不必要的 UI 操作。

建议MinimapHUD 在 Instantiate 后直接调用 PlaceCell 而不通过 Setup() 传入默认 pixelsPerCell。


🟡 N4MapInputHandler 使用旧版 Input System

float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");

若项目引入 Unity New Input System,此代码会失效(Input 轴未正确重定向时返回 0)。应通过 IInputServiceInputActions 接入。


五、待修复优先级

优先级 P1(高:影响运行性能)

ID 问题 位置 影响
P1-1 MinimapHUD.RefreshView O(N) 遍历 MinimapHUD.cs:137 大型地图(100+房间)房间切换卡顿

优先级 P2(中:影响编辑器体验)

ID 问题 位置 影响
P2-1 MapDatabaseEditor 错误行 GUIStyle 每帧分配 MapDatabaseEditor.cs:125-127 编辑器 GC 压力
P2-2 MapRoomDataEditor CELL_SIZE 与运行时比例不一致 MapRoomDataEditor.cs:16 策划混淆坐标系
P2-3 无 Undo 刷新回调(MapLayoutEditorWindow MapLayoutEditorWindow.cs SceneView Undo 后窗口不自动刷新
P2-4 ValidateAll 缺 #if UNITY_EDITOR 保护 MapRoomDataSO.cs:103 运行时构建包含 O(N²) 验证逻辑

优先级 P3(低:架构改进)

ID 问题 位置 影响
P3-1 缺少 RegionSO 数据资产 新文件 区域颜色/名称配置分散
P3-2 MapDesignSpec.md 文档缺失 Docs/Standards 策划无参考文档
P3-3 IMapService.Database 暴露具体类 IMapService.cs:12 限制未来数据源替换
P3-4 MapPanel 无 Overlay 扩展点 MapPanel.cs 新增覆盖层需修改源码
P3-5 GetRoomsByRegion LINQ 每次分配数组 MapManager.cs:114 低频但可优化

六、Round 6 总评

最终得分:85/100

架构解耦     ████████░░  9/10
性能         ████████░░  8/10  ← MinimapHUD O(N) 真实问题
编辑器扩展   ████████░░  8.5/10
数据设计     ████████░░  8/10
功能完整性   ████████░░  8/10
代码质量     ████████░░  8.5/10
可扩展性     ████████░░  8/10
策划友好度   ████████░░  8/10
─────────────────────────────
加权总分      85/100

总结

经过 Round 4 的 14 项修复,系统已从 Round 3 膨胀的 89 分回落至真实的 ~79 分,再经修复提升至当前的 85 分。Round 5 自评的 90 分存在约 +5 分的评估偏高。

系统优势:接口解耦体系完整、热路径性能全面优化、编辑器三工具功能齐全、数据驱动设计规范。

主要差距

  1. MinimapHUD 在大型地图下有 O(N) 遍历真实瓶颈
  2. 缺少 RegionSO 资产导致区域配置分散
  3. 编辑器工具有小的 GC 问题和 Undo 刷新缺口
  4. 策划侧缺乏设计规范文档

达到 90+ 分需解决 P1-1MinimapHUD 空间索引)和 P3-1RegionSO)两个主要缺口。



七、修复实施结果追踪

本章记录根据 Round 6 评估结论对代码执行的实际修复,确保报告与代码状态同步。

P1 修复(高优先级)

ID 状态 修改文件 说明
P1-1 MinimapHUD 空间索引 已修复 MinimapHUD.cs 新增 _spatialIndex Dict<Vector2Int,string> + _roomsInViewBuffer HashSetBuildSpatialIndex()OnEnable 构建;RefreshView step② 改为 O(viewRadius²) 空间索引查询替代 O(N) 全量遍历

P2 修复(中优先级 — 编辑器体验)

ID 状态 修改文件 说明
P2-1 MapDatabaseEditor GUIStyle 缓存 已修复 MapDatabaseEditor.cs 新增 _errorRowStyle 缓存字段 + GetErrorRowStyle() 惰性初始化;OnEnable 时置 null(编辑器皮肤切换时重建);替换 OnInspectorGUI 内每帧 new GUIStyle() 调用
P2-2 MapRoomDataEditor CELL_SIZE 说明 已修复 MapRoomDataEditor.cs Inspector HelpBox 补充坐标系说明:CELL_SIZE=1f 仅为 SceneView 可视化单位,格子布局数据(GridPosition/GridSize)是统一的格子单位,与运行时 worldUnitsPerCell 无需换算
P2-3 MapLayoutEditorWindow Undo 刷新 已修复 MapLayoutEditorWindow.cs 新增 OnEnable/OnDisable 注册/注销 Undo.undoRedoPerformedOnUndoRedo() 清除验证缓存并调用 Repaint()
P2-4 ValidateAll 编辑器保护 已修复 MapRoomDataSO.cs ValidateAll() 方法用 #if UNITY_EDITOR 包裹,O(N²) 验证逻辑不再进入运行时构建;两个调用方编辑器文件本身已在 #if UNITY_EDITOR 中,编译无变化

N3 修复(MinimapHUD 冗余位置写入)

ID 状态 修改文件 说明
N3 Setup 冗余位置设置 已修复 MinimapHUD.cs RefreshView step② 在 Instantiate+Setup 后立即调用 PlaceCell(cell, room) 设置正确的中心相对坐标,step③ PlaceCell 覆盖成为幂等确认操作

P3 未修复项(低优先级,架构级改动)

ID 状态 原因
P3-1 缺少 RegionSO 待后续 需新建 SO 类 + 编辑器工具 + 修改 MapManager,工作量较大
P3-2 MapDesignSpec.md 待后续 文档补充,不影响运行
P3-3 IMapService.Database 具体类 待后续 需调整接口,影响范围广
P3-4 MapPanel Overlay 扩展点 待后续 架构扩展,需设计方案
P3-5 GetRoomsByRegion LINQ 分配 待后续 低频调用,影响可忽略

修复后预估得分

维度 修复前 修复后预估
性能 8/10 8.5/10P1-1 空间索引修复主要瓶颈)
编辑器扩展 8.5/10 9/10P2-1 GUIStyle + P2-3 Undo 刷新均已修复)
数据设计 8/10 8/10ValidateAll 保护改善了构建质量,不影响功能评分)
其他维度 不变 不变
总分 85/100 ~87/100