4.5 KiB
Variadic
-
功能描述: 标识一个函数可以接受任意类型的多个参数(包括input/output).
-
元数据类型: bool
-
引擎模块: Blueprint, UHT
-
作用机制: 在Meta中加入Variadic
-
常用程度: ★★★
标识一个函数可以接受任意类型的多个参数(包括input/output).
在源码中搜索应用:然后配合UK2Node_ExecutePythonScript
UFUNCTION(BlueprintCallable, CustomThunk, Category = "Python|Execution", meta=(Variadic, BlueprintInternalUseOnly="true"))
static bool ExecutePythonScript(UPARAM(meta=(MultiLine=True)) const FString& PythonScript, const TArray<FString>& PythonInputs, const TArray<FString>& PythonOutputs);
DECLARE_FUNCTION(execExecutePythonScript);
蓝图的效果:
示例代码:
UCLASS(Blueprintable, BlueprintType)
class INSIDER_API UMyFunction_Variadic : public UBlueprintFunctionLibrary
{
public:
GENERATED_BODY()
public:
/*
[PrintVariadicFields Function->Struct->Field->Object /Script/Insider.MyFunction_Variadic:PrintVariadicFields]
(BlueprintInternalUseOnly = true, BlueprintType = true, CustomThunk = true, ModuleRelativePath = Function/Variadic/MyFunction_Variadic.h, Variadic = )
*/
UFUNCTION(BlueprintCallable, CustomThunk, BlueprintInternalUseOnly, meta = (Variadic))
static FString PrintVariadicFields(const TArray<FString>& Inputs, const TArray<FString>& Outputs);
DECLARE_FUNCTION(execPrintVariadicFields);
};
FString UMyFunction_Variadic::PrintVariadicFields(const TArray<FString>& Inputs, const TArray<FString>& Outputs)
{
check(0);
return TEXT("");
}
DEFINE_FUNCTION(UMyFunction_Variadic::execPrintVariadicFields)
{
FString str;
P_GET_TARRAY_REF(FString, Inputs);
P_GET_TARRAY_REF(FString, Outputs);
for (const FString& PythonInput : Inputs)
{
Stack.MostRecentPropertyAddress = nullptr;
Stack.MostRecentProperty = nullptr;
Stack.StepCompiledIn<FProperty>(nullptr);
check(Stack.MostRecentProperty && Stack.MostRecentPropertyAddress);
FProperty* p = CastField<FProperty>(Stack.MostRecentProperty);
FString propertyValueString;
const void* propertyValuePtr = p->ContainerPtrToValuePtr<const void*>(Stack.MostRecentPropertyContainer);
p->ExportTextItem_Direct(propertyValueString, propertyValuePtr, nullptr, nullptr, PPF_None);
str += FString::Printf(TEXT("%s:%s\n"), *p->GetFName().ToString(), *propertyValueString);
}
P_FINISH;
*(FString*)RESULT_PARAM = str;
}
示例效果:
打印:
CallFunc_MakeVector_ReturnValue:(X=1.000000,Y=2.000000,Z=3.000000) CallFunc_MakeLiteralDouble_ReturnValue:456.000000
原理:
普通的CustomThunk函数还有一些限制,参数名字和个数是在UFuntion里写死的,不能支持动态的个数。
目前,想使用Variadic功能,需要自定义蓝图节点用C++来为K2Node_CallFunction添加引脚。
想必是想要开发来同时实现K2Node以及对应的CustomThunk+Variadic方法,来保证使用上的安全性。
BlueprintInternalUseOnly也要加上,否则会自动生成普通的蓝图函数,达不到variadic的效果。
以下是不加BlueprintInternalUseOnly自动生成的版本:
实际应该是:然后再手动添加参数。
和Wildcard的区别是,Wildcard的参数是任意类型的,但个数是固定好的.
官方添加的和Python交互的功能 Added a Blueprint node for calling Python with args
官方的提交:
https://github.com/EpicGames/UnrealEngine/commit/61d0f65e1cded45ed94f0422eb931f446888e972
注释:
Implemented variadic function support for Blueprints
`Variadic functions are required to be a CustomThunk marked with the "Variadic" meta-data. They can then be used from a custom Blueprint node to accept arbitrary arguments at the end of their parameter list (any extra pins added to the node that aren't part of the main function definition will become the variadic payload).
Variadic arguments aren't type checked, so you need other function input to tell you how many to expect, and for a nativizied function, also what type of arguments you're dealing with.
#jira UE-84932 #rb Dan.OConnor
[CL 10421401 by Jamie Dale in Dev-Editor branch]`