Files
zeling_v2/Docs/Review/Minimap_Review_Round6_Independent.md
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 = 18fSceneView 中的可视化与实际地图 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 并手动填写 RoomId100 个房间需重复 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