版权声明:本文为CSDN博主「YakSue」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
正文
目标
使用 C++ 创建蓝图资源,并尝试给蓝图添加变量。 (引擎版本4.26)
步骤0. 创建测试用插件
使用 编辑器工具栏按钮 为模板创建插件。
使用这个模板的理由是它初始会有个按钮,可以用来触发操作:
之后将会替换这其中所触发的操作。
步骤1. 创建蓝图
对 KismetEditorUtilities.h 进行 include,因为创建蓝图需要用到其中的方法:
#include"Kismet2/KismetEditorUtilities.h"
对 AssetRegistryModule.h 进行include,因为需要 通知蓝图资源的创建 。
#include"AssetRegistryModule.h"
随后,将按钮触发的操作替换为:
// 资源名:
const FString AssetName = "YaksueTestBP";
// package 路径名:
const FString PackageName = "/Game/" + AssetName;
// 创建 Package
UPackage * Package = CreatePackage(nullptr, *PackageName);
// 创建蓝图
UBlueprint* NewBlueprint = FKismetEditorUtilities::CreateBlueprint(
AActor::StaticClass(), //ParentClass: the parent class of the new blueprint
Package, //Outer: the outer object of the new blueprint
FName(*AssetName), //NewBPName: the name of the new blueprint
EBlueprintType::BPTYPE_Normal, //BlueprintType: the type of the new blueprint (normal, const, etc)
UBlueprint::StaticClass(), //BlueprintClassType: the actual class of the blueprint asset (UBlueprint or a derived type)
UBlueprintGeneratedClass::StaticClass(), //BlueprintGeneratedClassType: the actual generated class of the blueprint asset (UBlueprintGeneratedClass or a derived type)
FName("YaksueTestContext")); //CallingContext: the name of the calling method or module used to identify creation methods to engine analytics/usage stats (default None will be ignored)
// 通知这个蓝图资源创建了
FAssetRegistryModule::AssetCreated(NewBlueprint);
// 编译蓝图
FKismetEditorUtilities::CompileBlueprint(NewBlueprint);
效果:点击按钮后会创建一个空白的蓝图:
步骤2. 为蓝图添加变量
关于 “添加变量” 这个功能,我翻阅代码找到了 FBlueprintEditorUtils::AddMemberVariable 接口。
通过字符串搜索,我找到了一处使用范例,在 \UE_4.26\Engine\Plugins\Tests\EditorTests\Source\EditorTests\Private\UnrealEd\EditorBuildPromotionTests.cpp :
关于变量的类型,通过 UEdGraphSchema_K2::PC_String 指定为“字符串”。
需要添加 BlueprintGraph 这个模块到 TestCppBP.Build.cs 的 PrivateDependencyModuleNames 中。因为 UEdGraphSchema_K2::PC_String 等其他的类型实际是个名字,为 static:
其值在 EdGraphSchema_K2.cpp 中指定:
如果不添加 BlueprintGraph 这个模块, UEdGraphSchema_K2::PC_String 等的值无法知道。
仿照范例添加字符串变量:
FEdGraphPinType StringPinType(
UEdGraphSchema_K2::PC_String, //PinCategory: Category of pin type
NAME_None, //PinSubCategory: Sub-category of pin type
nullptr, //PinSubCategoryObject: Sub-category object
EPinContainerType::None, //ContainerType
false, //bIsReference: Whether or not this pin is a value passed by reference or not
FEdGraphTerminalType()); //PinValueType: Data used to determine value types when bIsMap is true
FBlueprintEditorUtils::AddMemberVariable(NewBlueprint, "TestString", StringPinType);
效果,成功添加:
最终代码
...
#include"Actor.h"
#include"Kismet2/KismetEditorUtilities.h"
#include"Kismet2/BlueprintEditorUtils.h"
#include"AssetRegistryModule.h"
...
void FTestCppBPModule::PluginButtonClicked()
{
// 资源名:
const FString AssetName = "YaksueTestBP";
// package 路径名:
const FString PackageName = "/Game/" + AssetName;
// 创建 Package
UPackage * Package = CreatePackage(nullptr, *PackageName);
// 创建蓝图
UBlueprint* NewBlueprint = FKismetEditorUtilities::CreateBlueprint(
AActor::StaticClass(), //ParentClass: the parent class of the new blueprint
Package, //Outer: the outer object of the new blueprint
FName(*AssetName), //NewBPName: the name of the new blueprint
EBlueprintType::BPTYPE_Normal, //BlueprintType: the type of the new blueprint (normal, const, etc)
UBlueprint::StaticClass(), //BlueprintClassType: the actual class of the blueprint asset (UBlueprint or a derived type)
UBlueprintGeneratedClass::StaticClass(), //BlueprintGeneratedClassType: the actual generated class of the blueprint asset (UBlueprintGeneratedClass or a derived type)
FName("YaksueTestContext")); //CallingContext: the name of the calling method or module used to identify creation methods to engine analytics/usage stats (default None will be ignored)
// 通知这个蓝图资源创建了
FAssetRegistryModule::AssetCreated(NewBlueprint);
// 添加一个字符串类型的变量
{
FEdGraphPinType StringPinType(
UEdGraphSchema_K2::PC_String, //PinCategory: Category of pin type
NAME_None, //PinSubCategory: Sub-category of pin type
nullptr, //PinSubCategoryObject: Sub-category object
EPinContainerType::None, //ContainerType
false, //bIsReference: Whether or not this pin is a value passed by reference or not
FEdGraphTerminalType()); //PinValueType: Data used to determine value types when bIsMap is true
FBlueprintEditorUtils::AddMemberVariable(NewBlueprint, "TestString", StringPinType);
}
// 编译蓝图
FKismetEditorUtilities::CompileBlueprint(NewBlueprint);
}
...