3.1 Asset Registry:资产查询与批量处理

Asset Registry 是什么

Asset Registry(资产注册表)是编辑器维护的「资产元数据库」:每个资产的类型、路径、标签、依赖、引用都记录在案。工具想批量找资产,不要扫描磁盘,查注册表是毫秒级的。官方文档见「资产注册表」(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/asset-registry-in-unreal-engin-62bd)。

基础查询

FAssetRegistryModule& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
IAssetRegistry& Registry = AR.Get();

// 按路径 + 类型查
FARFilter Filter;
Filter.PackagePaths.Add(TEXT("/Game/Items"));
Filter.ClassNames.Add(TEXT("WeaponDataAsset"));      // 想要的类型
Filter.bRecursivePaths = true;

TArray<FAssetData> Assets;
Registry.GetAssets(Filter, Assets);
// Assets[i].ObjectPath / PackageName / AssetClass / TagValues

关键:FAssetData 不加载资产,它只是元数据。拿 ObjectPath 后按需 LoadObject。

Tag 与值查询

资产里的属性会作为 Tag 存进注册表(对数据资产、某些对象支持):

// 找所有「品质=传说」的武器(假设 WeaponDataAsset 有 Rarity 属性)
Filter.TagsAndValues.Add(TEXT("Rarity"), TEXT("Legendary"));

查询成本极低,适合做「按属性筛选」的检查工具。

引用关系:两个方向的查询

// 谁引用了我?(找「这个资产被谁用」)
Registry.GetReferencers(PackageName, OutReferencers);

// 我引用了谁?(找「这个资产依赖谁」)
Registry.GetDependencies(PackageName, OutDependencies);

用途:

  • 删除前检查:删一个材质前看有没有网格体引用它
  • 找孤儿:没人引用的资产(可清理候选)
  • 影响面分析:改一个数据表会影响哪些关卡

蓝图里怎么查

Editor Scripting / Asset Registry 节点把上面的能力开放给蓝图:

  • Get Assets by Filter(筛选资产)
  • Get Assets by Class(按类)
  • Get Referencers / Get Dependencies
  • Get Asset Tags

配合 EUW 做工具,整个链路蓝图可完成,不用 C++。

批量处理的事务性

批量修改必须包在 Transaction 里,这样能整体撤销:

{
    FScopedTransaction Trans(FText::FromString("批量调整属性"));
    for (auto& AssetData : Assets)
    {
        UWeaponDataAsset* W = Cast<UWeaponDataAsset>(AssetData.GetAsset());
        if (W) { W->Modify(); W->Damage += 10; W->MarkPackageDirty(); }
    }
}
// 一次 Ctrl+Z 回滚全部

三个细节缺一不可:Modify()(标记资产进入撤销栈)、改值、MarkPackageDirty()(标记需保存)。漏掉 Modify 的工具,撤销时行为是「撤销一半」。

异步扫描大项目

几万资产的项目,首次查询注册表时它可能还在后台扫描。稳健做法:

if (!Registry.IsLoadingAssets())
{
    DoQuery();
}
else
{
    // 注册表扫描完成委托
    Registry.OnFilesLoaded().AddLambda([](){ DoQuery(); });
}

工具启动快、数据稍后到达——这比「启动卡 30 秒」体验好得多。

性能要点

禁止 应该
扫描磁盘目录(IPlatformFile 遍历) 查 AssetRegistry
每个资产都 LoadObject 试探类型 用 AssetData.AssetName/Class 过滤后再加载
同步加载上千资产 分批异步
工具 UI 绑定里查注册表 缓存后读缓存(见 2.5)

心得:资产工具的性能分水岭就在「用 AssetData 元数据够不够」。能用元数据解决的筛选/统计绝不去加载资产——查询 1 万个资产元数据 ~100ms,加载 1 万个资产 >10 秒。