UE4构建多输出执行引脚蓝图节点(同步节点与异步节点)

前言

在蓝图中,我们经常能看到一些节点具备多输出执行引脚(图一)。我们知道程序执行时,按照执行流程,根据给定的条件可以出现执行分支,在蓝图中使用Branch节点可以完成。但是在设计节点时(C++中),应该如何完成节点封装后,具备多输出执行引脚?这是问题的关键。

图一

首先,我们先认识下图一的节点

  • 普通C++中编写的蓝图函数节点,具有一个输出执行引脚
  • 注意,这是宏,在蓝图中编写,宏在构建时时可以加入多输入引脚与多输出引脚的。可直接在蓝图中产出
  • 在C++中构建的函数,具有多输出执行引脚
  • 在C++中构建的函数,具有多输出执行引脚

其中三条和四条的描述是一样,那是否它们是相同的呢?不然,第四个节点和第三个节点的最大区别在于:节点的右上角多了一个时钟标记。在蓝图中,这个标记代表节点是异步节点

所以节点三和四的最大区别在于执行时是否出现异步输出

C++中编写多输出执行引脚节点(非异步)

构建多输出执行引脚节点(同步)比较简单。

  • 构建枚举项,用来描述输出引脚名称
  • 编写函数,并标记为暴露到蓝图
  • 添加枚举参数,参数为引用方式
  • 增加导出枚举为执行引脚标记指令
构建枚举
UENUM(BlueprintType)
enum class EBlueprintExecNodePin : uint8
{
	Success,
	Fail
};
编写函数声明
UFUNCTION(BlueprintCallable, meta=(ExpandEnumAsExecs="Result"))
static void MultiExecNode(EBlueprintExecNodePin& Result);
构建函数定义
void UMultiExecBPLibrary::MultiExecNode(EBlueprintExecNodePin& Result)
{
	//输出引脚,如果希望是Success,则直接赋值Result为Success,反之亦然
	Result = EBlueprintExecNodePin::Success;
}

C++中编写多输出执行引脚节点(异步)

异步蓝图节点构建要比其他蓝图节点编写稍微复杂些。首先在常规编码中,异步逻辑我们需要解决几个问题,第一回调函数的编写,第二在操作异步中不能释放掉调用对象,否则回调通知将会失败,第三构建异步线程,区别于当前逻辑线程。但是在蓝图中,虚幻引擎设计者简化了异步构建逻辑,将复杂性隐藏在C++中,使得我们操作的任何异步节点都非常的简单。(蓝图中是否可以构建异步节点,不在讨论范围,从角度来说,应该是不建议)

构建步骤
  • 编写C++类,继承UBlueprintAsyncActionBase类
  • 构建动态多播对象类型
  • 构建多播对象
  • 编写蓝图函数节点
  • 执行异步通知广播
编写C++类

你可以选择在创建类时继承BlueprintAsyncActionBase父类,或是在创建好的类中修改继承父类均可

图二
构建动态多播类型

动态多播代理类型构建时,可以选择带有参数,或是不带有参数。可根据实际设计意图进行设计!

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintAsyncNodePinResult, int32, Result);
构建多播对象
UPROPERTY(BlueprintAssignable)
FBlueprintAsyncNodePinResult OnSuccess;
UPROPERTY(BlueprintAssignable)
FBlueprintAsyncNodePinResult OnFail;

注意必须加标记宏指令,否则将无法在蓝图中被应用

编写蓝图函数节点
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
static UBlueprintAsyncNode* AsyncDelay(float Delay);

BlueprintInternalUseOnly标记指令将函数对蓝图隐藏,只用于内部操作。意图:真正的蓝图异步节点是被特殊处理的,我们不能直接将此节点暴露到蓝图(大家可以尝试去掉后,将在蓝图中看到两个AsyncDelay节点),框架会将此函数进行再次设计,以提供到蓝图中使用。

现在编译就可以在蓝图中看到暴露的节点了
图三

编写异步蓝图节点当然并没有这么简单,我们只是单独阐述了过程,下篇文章(传送门)将细致讲解下如何编写异步蓝图节点

源码

头文件

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "BlueprintAsyncNode.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintAsyncNodePinResult, int32, Result);
/**
 * 
 */
UCLASS()
class UECPP_API UBlueprintAsyncNode : public UBlueprintAsyncActionBase
{
	GENERATED_BODY()

	UPROPERTY(BlueprintAssignable)
	FBlueprintAsyncNodePinResult OnSuccess;
	UPROPERTY(BlueprintAssignable)
	FBlueprintAsyncNodePinResult OnFail;

	UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
	static UBlueprintAsyncNode* AsyncDelay(float Delay);
};

源文件

// Fill out your copyright notice in the Description page of Project Settings.

#include "BlueprintAsyncNode.h"

UBlueprintAsyncNode* UBlueprintAsyncNode::AsyncDelay(float Delay)
{
	return nullptr;
}

祝各位在虚幻中玩的愉快~~

虚幻版本 V4.21.2

添加评论

您的电子邮箱地址不会被公开。