现在有C++类C_A,蓝图类B_A,B_B,B_C(都继承于C_A),现在想在编辑器做一个资源选择界面,选择的对象所有继承于C_A的所有蓝图类?
主要是使用”ContentBrowser”模块的CreateAssetPicker函数,”ContentBrowser”模块就是编辑器中的内容浏览器的部分。调用CreateAssetPicker函数前需要先构造FAssetPickerConfig的参数,这个参数主要是选择资源过滤条件。调用如下:
static const FName PosParentClassTagName(TEXT("ParentClass"));
static const FString PosClassPath(TEXT("Class'/Script/AAA.C_A'"));
TSharedRef<SWidget> FPaladinSequenceTemplete::CreateAssetPicker(FName AssertName, FOnAssetSelected OnAssetSelected,bool Actor)
{
FAssetPickerConfig AssetPickerConfig;
{
AssetPickerConfig.OnAssetSelected = OnAssetSelected;
AssetPickerConfig.bAllowNullSelection = false;
AssetPickerConfig.InitialAssetViewType = EAssetViewType::List;
AssetPickerConfig.Filter.bRecursiveClasses = true;
AssetPickerConfig.Filter.ClassNames.Add(AssertName);
AssetPickerConfig.Filter.TagsAndValues.Add(PosParentClassTagName, PosClassPath);
}
FContentBrowserModule& ContentBrowserModule = FModuleManager::Get().LoadModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser"));
return SNew(SBox)
.WidthOverride(300.0f)
.HeightOverride(300.f)
[
ContentBrowserModule.Get().CreateAssetPicker(AssetPickerConfig)
];
}
有几个点需要注意:
1. AssetPickerConfig.Filter.ClassNames 这个需要传入的是UBlueprint的ClassName而不是你C++类的ClassName,你可以尝试在内容浏览器中查找你的资源,你会发现过滤条件是蓝图类,这是一个道理。
2. 过滤条件仅仅是UBlueprint是不够的,这样会把所有的蓝图类都找出来,还得加进一步的限制条件。那么咱的限制条件是蓝图类并且父类是AAA.C_A的。这时候需要用到另一个参数Filter.TagsAndValues。查看UBlueprint类的声明可以发现一些标识为AssetRegistrySearchable的属性,这个属性就是用在这里提供查询的。我们的过滤条件是UBlueprint中的ParentClass为C_A的所有蓝图类,那么就把这个键值对插入到TagsAndValues就可以了。
通过上面的步骤我们已经可以创建过滤窗口了,等用户选择资源后,会调用资源选择的回调函数(AssetPickerConfig.OnAssetSelected),参数为const FAssetData&类型。假设用户选择的B_A,需要注意的点:
1. FAssetData.AssetClass 依然为UBlueprint类型。不可能是C_A或者是中间生成的C++类型。
2. FAssetData.GetAsset()返回UBlueprint实体的指针类型。
3. 我们在C_A声明一个函数,UFUNCTION指定为BlueprintImplementableEvent表示需要蓝图类来实现,函数名为int GetDebugInfo(); B_A,B_B,B_C分别继承C_A并重写函数GetDebugInfo并依次返回1,2,3。假如我们拥有蓝图类的实体那么可以直接调用GetDebugInfo获取到数据;假如我们拥有的是蓝图类的TSubClassOf<C_A>的数据,那么可以通过调用CDO转换为C_A然后调用GetDebugInfo获取数据;假如我们只有FAssetData数据,那么可以通过FAssetData.GetAsset获取到UBlueprint的实体数据,然后可以获得蓝图类生成的对应的C++类的类型数据UBlueprint.GeneratedClass,然后获取到UBlueprint.GeneratedClass的CDO,然后再调用GetDebugInfo即可。
每个蓝图类B_A,B_B,B_C都有一个对应的C++类(应该是蓝图系统生成的),类型数据存储在UBlueprint.GeneratedClass中。