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 重复,请确认保留哪个」。工具报告的第一读者是人,描述不清的报错等于没有。
