前言
引用查看器(ReferenceViewer)可以显示资源引用关系数据,我想要知道这个数据是如何得到的。因此从它的界面代码开始一步步往里看。
(到最后才发现,得到引用关系数据的接口很简单,而且是蓝图可访问的,详见本篇的【使用蓝图接口获得引用关系数据】部分)
1. 界面的代码
右键资源点 Reference Viewer 可以查看其引用关系
它所引用的,和引用它的,都可以看到:
首先,我想要找到这里Slate界面的代码。
我尝试全局搜索“ReferenceViewer”(可以用 Everything 工具来搜索),幸运的是直接找到了文件 “SReferenceViewer.h”。路径:
Engine\Plugins\Editor\AssetManagerEditor\Source\AssetManagerEditor\Private\ReferenceViewer\SReferenceViewer.h
为了验证,可以在这里下断点,可以看到每次打开引用查看器都会走到这里:
2. 创建节点的逻辑
ReferenceViewer相关的代码文件并不多。
回想之前学习UE节点图表编辑器的基本概念可直接找到几个最感兴趣的内容:
UEdGraph_ReferenceViewer
代表了这个网络图
UEdGraphNode_Reference
代表了其中的一个节点的数据。
SReferenceNode
包含了节点的界面相关的内容。
因此,只要在UEdGraphNode_Reference
的构造函数中下断点,就可以捕捉到每次创建新节点的堆栈。
对于这个测试的资源而讲,由于有三个节点,所以显然创建了三次。
这三次都从 UEdGraph_ReferenceViewer::ConstructNodes 中进入:
首先是创建根节点(这里是这个立方体StaticMesh)
然后是创建引用它的节点(这里是摆放它的关卡)
最后是它所引用的节点(这里是它的材质)
调用RecursivelyConstructNodes
函数的bReferencers
参数代表了是“引用它的”还是“它所引用的”。这点从后续它所影响的创建节点的位置也可以看出:
3. 得到引用关系数据的逻辑
从RecursivelyConstructNodes
函数的名字也可以看出,他的形式是递归的。
而本轮调用时给定的参数Identifiers
,其实就是上一轮的Referencers
(准确来说是Referencers
这个map的key)
比如这里的Identifiers
是立方体StaticMesh,而Referencers
是它的材质。
那么如何得到Referencers
就是关键。
可以调试出,它在GetSortedLinks
这个函数中被赋予了值:
继续进入GetSortedLinks
,可以看到最终它使用了AssetRegistry.GetReferencers
和AssetRegistry.GetDependencies
来获得引用数据关系。
使用蓝图接口获得引用关系数据
其实,这两个接口直接用蓝图就可以调用。
获得这个资源有谁在引用它:
我这里将会输出:
/Game/ThirdPersonCPP/Maps/ThirdPersonExampleMap
获得这个资源在引用谁:
我这里将会输出:
/Game/Geometry/Meshes/CubeMaterial
如果用Python,则代码如下:
#获得AssetRegistry
ar = unreal.AssetRegistryHelpers.get_asset_registry()
#选项(一会儿调用接口时用到)
option = unreal.AssetRegistryDependencyOptions()
#谁引用它:
refs = ar.get_referencers("/Game/Geometry/Meshes/1M_Cube",option)
print(refs)
#它引用谁:
refs = ar.get_dependencies("/Game/Geometry/Meshes/1M_Cube",option)
print(refs)
输出:
LogPython: ["/Game/ThirdPersonCPP/Maps/ThirdPersonExampleMap"]
LogPython: ["/Game/Geometry/Meshes/CubeMaterial"]