量子计算9 发表于 2022-8-1 20:51

unreal自定义蓝图节点2

之前已经简单说了以下蓝图节点的自定义创建,但是在真的项目中还是缺少很多的!在这里就做一个补充说明!
大纲

这里补充的内容大致有一下 - 带参数的函数 - 有返回值的函数
带参数的函数

基本的创建方法可以看之前的文章记录; 先简单定义一个运行时的带参方法
UCLASS()
class UNREALGAMEDEMO_API UCustomRunningNode : public UObject
{
public:
    GENERATED_BODY()
    UFUNCTION(BlueprintCallable)
    static void TestBlueprintNode3(FString arg1, int arg2)
    {
      UE_LOG(LogUnrealGameDemo, Display, TEXT("UCustomRunningNode::TestBlueprintNode3"));
      UE_LOG(LogUnrealGameDemo, Display, TEXT("arg1:%s arg2:%d"), *arg1, arg2);
    }
};
创建AllocateDefaultPins,这里为了简单对应,直接使用和函数的参数一样的类型就可以了,以后再说说类型转换的问题!
void UCustomNode2::AllocateDefaultPins()
{
    Super::AllocateDefaultPins();
    // input
    CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);
    // 两个参数
    CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, TEXT("Arg1"));
    CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Int, TEXT("Arg2"));
    // output
    CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);
}




这个时候编译时错误的,我们必须要把其他的给写完成!
void UCustomNode2::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
{
    Super::ExpandNode(CompilerContext, SourceGraph);
    auto execPin = GetExecPin();
    auto thenPin = GetThenPin();
    if (execPin && thenPin)
    {
      // 和之前一样!
      auto functionName = GET_FUNCTION_NAME_CHECKED(UCustomRunningNode, TestBlueprintNode3);
      auto function = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
      function->FunctionReference.SetExternalMember(functionName, UCustomRunningNode::StaticClass());
      function->AllocateDefaultPins();
      CompilerContext.MovePinLinksToIntermediate(*execPin, *(function->GetExecPin()));
      CompilerContext.MovePinLinksToIntermediate(*thenPin, *(function->GetThenPin()));

      // 获取蓝图编辑界面中的pin
      auto inputArg1Pin = FindPin(TEXT("Arg1"));
      auto inputArg2Pin = FindPin(TEXT("Arg2"));
      // 获取函数中的参数的Pin
      auto funcArg1 = function->FindPin(TEXT("arg1"));
      auto funcArg2 = function->FindPin(TEXT("arg2"));
      // pin转移!
      MoveLink(CompilerContext, inputArg1Pin, funcArg1);
      MoveLink(CompilerContext, inputArg2Pin, funcArg2);
    }
    BreakAllNodeLinks();
}

void UCustomNode2::MoveLink(FKismetCompilerContext& CompilerContext, UEdGraphPin* sourcePin, UEdGraphPin* targetPin)
{
    // 要区分有没有Pin连接,有和没有两种情况要分开处理!
    if (sourcePin->LinkedTo.Num() > 0)
    {
      CompilerContext.MovePinLinksToIntermediate(*sourcePin, *targetPin);
    }
    else
    {
      // 默认值的复制!
      targetPin->DefaultObject = sourcePin->DefaultObject;
      targetPin->DefaultValue = sourcePin->DefaultValue;
      targetPin->DefaultTextValue = sourcePin->DefaultTextValue;
    }
}
到这里我们就能编译,测试也能调用和传递!
Display      LogUnrealGameDemo         UCustomRunningNode::TestBlueprintNode3
Display      LogUnrealGameDemo         arg1:1111 arg2:1有返回值的函数

运行时的函数修改返回值
UFUNCTION(BlueprintCallable)
static int TestBlueprintNode3(FString arg1, int arg2)
{
    UE_LOG(LogUnrealGameDemo, Display, TEXT("UCustomRunningNode::TestBlueprintNode3"));
    UE_LOG(LogUnrealGameDemo, Display, TEXT("arg1:%s arg2:%d"), *arg1, arg2);
    return 64*arg2;
}
如果函数是有返回的话,在前面的代码中先添加以个default的输出pin
void UCustomNode2::AllocateDefaultPins()
{
    Super::AllocateDefaultPins();
    ...
    // 返回
    CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Int, TEXT("Result"));
}
ExpandNode中在传完参的后面添加结果的获取和传递!
void UCustomNode2::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
{
    Super::ExpandNode(CompilerContext, SourceGraph);
    ...
    if (execPin && thenPin)
    {
      ...
      // 获取函数的返回pin
      auto returnPin = function->GetReturnValuePin();
      // 获取蓝图编辑界面中的Pin
      auto resultPin = FindPin(TEXT("result"));
      // 结果复制!
      if(resultPin->LinkedTo.Num() > 0)
      {
            CompilerContext.MovePinLinksToIntermediate( *resultPin, *returnPin);
      }

    }
    BreakAllNodeLinks();
}
这里的结果要注意,没有Pin连接输出的时候,是不需要复制的,在复制前世必须要有Pin的连接!!!
结果类似这样!

页: [1]
查看完整版本: unreal自定义蓝图节点2