3.5 实战:一个批量检查器工具的完整设计

需求

检查全项目武器数据资产:① 有没有 ID 重复 ② 有没有伤害 ≤ 0 ③ 有没有引用了不存在的图标资源。输出报告 + 一键修复(ID 冲突需人工,伤害自动修正为默认值)。

这是「检查类工具」的典型形状——比「生成类工具」更有价值(见 1.1)。

架构

工具结构:
├── EUW 界面(Slate 蓝图)
│   ├── 「扫描」按钮 → 调检查
│   ├── ListView:问题列表(类型、资产、详情)
│   ├── 详情区:选中问题的说明
│   └─ 「修复可自动修的」按钮
├── 检查逻辑(蓝图或 Python)
│   ├── AssetRegistry 查资产(元数据阶段)
│   ├── 加载资产做校验(按需加载阶段)
│   └── 生成报告 FStruct(问题数组)
└── 报告结构体
    { ProblemType, AssetPath, Description, CanAutoFix, Payload }

分阶段设计(性能关键)

# 阶段1:元数据
assets = registry.get_assets(filter)
# → 只看 AssetData,筛掉类型不符的(0 加载)

# 阶段2:按需加载校验
for ad in assets:
    a = ad.get_asset()                     # 只加载需要的
    check_id(a); check_damage(a); check_icon_reference(a)

不做阶段化的典型后果:一上来全部加载,工具卡 40 秒。分阶段后,扫描报告几秒出框架,细节校验逐步填充(也可以边加载边更新 UI)。

检查的三个例子

def check_damage(a):
    if a.damage <= 0:
        report(ProblemType.BAD_VALUE, a, "damage=%d 非法" % a.damage, auto_fix=True)

def check_icon_reference(a):
    if a.icon and not unreal.EditorAssetLibrary.does_asset_exist(a.icon.load_path()):
        report(ProblemType.MISSING_REF, a, "图标资源不存在", auto_fix=False)

def check_id(a, seen_ids):
    if a.item_id in seen_ids:
        report(ProblemType.DUP_ID, a, "ID 与 %s 重复" % seen_ids[a.item_id], auto_fix=False)
    seen_ids[a.item_id] = a.get_name()

报告的呈现

UI 的核心原则:问题一眼可分诊。

列 内容
类型徽章 颜色编码(红=必须修/黄=警告/绿=建议)
资产路径 一点就在内容浏览器里定位(Content Browser Focus)
说明 直接告诉用户「这是什么问题、怎么修」
可自动修 勾选框(可自动修的允许批量勾选)

「点击报告行 → 内容浏览器定位资产」这个交互加不了几行代码,但对排查体验是质的提升:

unreal.EditorAssetLibrary.sync_browser_to_objects([asset_path])

修复

  • 自动修复:改值 → Modify() → MarkPackageDirty → 批量保存
  • 人工修复(ID 冲突):工具不猜——列出「哪些资产互撞」,让用户决定保留谁
  • 修复后重验:修完必须重跑一次全检查,确认问题真的消失(防止修复逻辑自身有 bug)

扩展:检查器规模化

一个检查器做大了就是「项目质量保证工具集」。扩展点:

  • 规则可配置:把「damage ≤ 0 算错」的阈值放配置,策划可调
  • 规则包:不同项目阶段跑不同子集(开发期宽松、发布前严格)
  • 报告导出:CSV/JSON,CI 里当作门禁(第五章)
  • 白名单:已知恶意的问题允许标记忽略(避免长期报同样的问题让人麻木)

效果复盘

这个工具上线一个月内:

  • 发现 3 处 ID 重复(策划手工填的)
  • 发现 12 个资产的图标引用丢失(移动资源时没更新引用)
  • 修复 200+ 个资产的默认值错误

工具开发成本约 1 天,产出 = 避免 N 个线上配置事故。

心得:检查类工具的精髓在「给问题一个人话的描述」。工具输出的「DUP_ID: 1042 in /Game/Items/W_Sword」远不如「ID 1042 与 W_Sword 重复,请确认保留哪个」。工具报告的第一读者是人,描述不清的报错等于没有。