Files
zeling_v2/Docs/Review/Minimap_Review_Round21_Independent.md
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

8.5 KiB
Raw Blame History

小地图系统独立评审 Round 21

评审时间R21基于 R20 全部修复已落地的代码基线)
评审范围Assets/_Game/Scripts/World/Map/ 全部 19 个运行时文件 + 4 个编辑器扩展文件
评分基准:专业 2D Metroidvania 编辑器扩展标准(架构解耦 / 高性能 / 可扩展 / 开发者友好)


R20 修复确认

编号 内容 状态
R20-N1 RunRevealAnim 包装协程,完成后 _revealCoroutines.Remove(roomId) 确认L214-218
R20-N2 ChooseDisplayIcon 集中到 MapRoomDataSOMapPanel/MinimapHUD 改单行委托 确认L61-69 / L478-480 / L367-368

各维度评分

1. 架构设计Architecture 18.5 / 20

亮点

  • ServiceLocator + 4 接口层IMapService / IPinService / IPlayerPositionProvider / ITeleportService完全解耦
  • 事件驱动C# Action无轮询
  • ISaveable 三处防御性拷贝对称实现
  • MapRoomCellUI 在 MapPanel / MinimapHUD 共享,零重复 Prefab
  • ChooseDisplayIcon R20-N2 后唯一入口,无漂移风险

新发现问题 N1中等严重MinimapHUD 缺少 LateUpdate 服务重试机制

MapPanel.LateUpdate 对未就绪的服务执行重试:

// MapPanel.cs L169-170
if (!_servicesReady)
    SubscribeServices();

MinimapHUD 仅在 AwakeOnEnable 中调用 SubscribeServices()无 LateUpdate 重试
MapPlayerTrackerIPlayerPositionProvider[DefaultExecutionOrder],初始化顺序不确定:

  • MinimapHUD.Awake 先于 MapPlayerTracker.Awake 执行 → _playerProvider 永久为 null
  • 后果:玩家圆点不渲染,OnRoomChanged 永不触发HUD 完全静止

扣分1.5


2. 性能Performance 19.5 / 20

亮点

  • MapPanel 3 对象池Cell / Pin / ExitMinimapHUD 2 对象池Cell / Pin
  • O(viewRadius²) 空间索引查询(共享 MapDatabaseSO._cellToRoom
  • _servicesReady 短路MapPanel消除每帧 ServiceLocator 查询
  • _revealCoroutines 自清理R20-N1
  • 复用缓冲区:_toRemove / _roomsInViewBuffer / _newlyAddedBuffer
  • PinsVersion 脏检查 + 玩家位置脏检查
  • _regionCache 懒加载,避免 LINQ 全扫

说明(信息级,不扣分):MapPanel.BuildGrid 末尾调用 LayoutRebuilder.ForceRebuildLayoutImmediate
_scrollRect.content 含 ContentSizeFitter此调用是必要的确保 CenterOnCurrentRoom 读到正确 content 尺寸);无 LayoutGroup 时代价极低。设计合理。

扣分0.5MinimapHUD 无 _servicesReady 短路,每次 OnEnable 均执行三次 ServiceLocator 查询)


3. 代码质量Code Quality 18.5 / 20

亮点

  • CurrentZoom 属性R19-N1消除双份状态
  • RunRevealAnim 自清理协程R20-N1
  • ChooseDisplayIcon 单一职责集中R20-N2
  • OnValidate RoomFlags 迁移兼容
  • HasCustomExitPos 语义布尔替代哨兵值
  • [Obsolete] + [HideInInspector] 废弃字段注解完整

新发现问题 N2轻微MapPanel 集合字段缺少 readonly 修饰

MinimapHUD 同类字段已标 readonly,两者不一致:

// MinimapHUD.cs已正确标注
private readonly Dictionary<string, MapRoomCellUI> _cells     = new();
private readonly List<Image>                       _pinImages = new();
private readonly Stack<Image>                      _pinPool   = new();
private readonly Stack<MapRoomCellUI>              _cellPool  = new();

// MapPanel.cs缺少 readonly可被意外重新赋值
private Dictionary<string, MapRoomCellUI> _cells     = new();
private List<Image>                       _pinImages = new();
private Stack<Image>                      _pinPool   = new();
private Stack<MapRoomCellUI>              _cellPool  = new();
private Stack<Image>                      _exitPool  = new();
private List<Image>                       _exitImages= new();

_revealCoroutines 已正确标 readonly,其余集合字段漏标。

扣分1.0N2 readonly 不一致)+ 0.5MapInputHandler _zoomOnScroll 仍作为局部累加器,与 _zoomTarget.localScale.x 功能重叠,配置错误时存在漂移风险)


4. 编辑器扩展Editor Tools 14.5 / 15

亮点

  • MapLayoutEditorWindow:缩放/平移/拖拽/搜索/区域着色/验证/Undo/热改
  • _cachedZoomForStyle 脏检查Style 不在每帧重建
  • _noResultStyle 首次初始化缓存R18-N2
  • MapDatabaseEditorMapRoomDataEditorMapRoomAutoRegister 覆盖完整工作流
  • DrawExitLines 去重缓存(_drawnExitPairs

扣分0.5(信息级:MapLayoutEditorWindow 无单元测试覆盖)


5. 功能完整性Feature Completeness 14.5 / 15

亮点

  • 三级可见性Unknown / Explored / Mapped完整实现
  • 类型图标优先级Override > SavePoint > Boss > Shop > Teleport
  • Pin 系统(持久化、类型化、可视半径内渲染)
  • 出口连接线 + Fallback 位置R13-N1
  • 区域检测与 RegionChanged 事件
  • 存档/读档ISaveable
  • 房间发现动画RevealAnim 自清理)
  • 全屏地图 + 角落 HUD 双视图

N1 影响:若 MinimapHUD 初始化顺序不利,玩家圆点和 HUD 响应将缺失,属功能可靠性问题。扣分0.5


6. 输入系统Input System 9.5 / 10

亮点

  • 全部使用 InputSystemInputReaderSO
  • MapInputHandlerNavigate / MapCenter / OnScroll
  • MinimapInputHandlerCycleMinimapZoom
  • OnEnable/OnDisable 对称订阅/取消

扣分0.5(信息级:MapInputHandler._zoom_panel.CurrentZoom 职责轻微重叠)


综合评分

维度 满分 得分
架构设计 20 18.5
性能 20 19.5
代码质量 20 18.5
编辑器扩展 15 14.5
功能完整性 15 14.5
输入系统 10 9.5
合计 100 95.0

R21 较 R2094.2)略有提升,主要因 R20 修复全部落地确认;
N1服务重试缺失是本轮最高优先级问题。


问题清单与修复建议

N1 — MinimapHUD 缺少服务重试(高优先级)

根因MapPlayerTracker[DefaultExecutionOrder],可能晚于 MinimapHUD 注册服务。

修复方案 A推荐防御性最强:在 MinimapHUD.LateUpdate 中补充重试。

// MinimapHUD.cs
private bool _servicesReady;

private void LateUpdate()
{
    if (!_servicesReady)
        SubscribeServices();
    UpdatePlayerDot();
    RenderPinsIfDirty();
}

private void SubscribeServices()
{
    // 原有逻辑不变,末尾加:
    if (_playerProvider != null && _mapSvc != null && _pinService != null)
        _servicesReady = true;
}

修复方案 B互补:给 MapPlayerTracker 加执行顺序,确保早于无顺序 MonoBehaviour 注册。

[DefaultExecutionOrder(-600)]  // 晚于 MapManager(-700),早于默认 0
public class MapPlayerTracker : MonoBehaviour, IPlayerPositionProvider

建议两个方案同时实施B 保证常规路径A 防御异常路径。


N2 — MapPanel 集合字段缺少 readonly(低优先级)

修复:在 MapPanel.cs 的集合字段声明处补充 readonly

private readonly Dictionary<string, MapRoomCellUI> _cells     = new();
private readonly List<Image>                       _pinImages = new();
private readonly Stack<Image>                      _pinPool   = new();
private readonly Stack<MapRoomCellUI>              _cellPool  = new();
private readonly Stack<Image>                      _exitPool  = new();
private readonly List<Image>                       _exitImages= new();

N3 — MinimapHUD.OnDisable 未重置 _servicesReady(伴随 N1 修复引入)

实施 N1 修复后,若 _servicesReady 不在 UnsubscribeServices / OnDestroy 时重置,销毁后重建场景的实例将跳过重订阅。

private void UnsubscribeServices()
{
    _servicesReady = false; // 补充
    // 其余原有逻辑不变
}

评分历史

轮次 评分 关键改动
R14 92.3
R15 91.3
R16 92.5
R17 93.0
R18 93.8 MinimapHUD 废弃 _onMapUpdated 订阅
R19 93.8 CurrentZoom 属性_revealCoroutines 防泄漏
R20 94.2 RunRevealAnim 自清理ChooseDisplayIcon 集中
R21 95.0 R20 修复确认;识别 N1服务重试缺失N2readonlyN3执行顺序