UE4异步蓝图节点设计与实现(单线程)

文章介绍了如何在UE4中自定义蓝图异步节点,特别是使用C++的BlueprintAsyncActionBase类创建一个基于异步的计时器节点。该节点监视TickActor的计数器,当达到目标值时触发Success多播委托,否则触发Fail委托。
摘要由CSDN通过智能技术生成

UE4异步蓝图节点设计与实现(单线程)

在UE4的蓝图中,有许多节点的执行是独立于主线程的,例如定时器或者一些延迟操作,我们不能在主线程中执行,这样会导致游戏画面出现暂停等情况。

在蓝图中,最常见的一个异步节点就是delay节点,在异步节点中我们也可以分为使用单线程还是多线程实现的异步节点。

在这里插入图片描述

在蓝图中也存在许多异步节点,但是在实际开发中,根据实际需要,我们可能需要对场景中多个对象进行异步操作,这个时候就需要我们自定义的实现UE4中蓝图异步节点。

其中,最主要的就是使用C++中的BlueprintAsyncActionBase类来自定义蓝图异步节点,注意异步节点的输出需要绑定多播委托。

下面我们设计了一个基于异步的定时器节点,其目的非常简单,即通过计时器不断访问TickActor中的计数,当计数值大于等于目标值时,则Success多播相应,反之则Fail响应。

MyBluprintAsyncActionBase.h

#pragma once
#include "CoreMinimal.h"
#include "TickTestActor.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "MyBlueprintAsyncActionBase.generated.h"

//异步节点的输出需要各自绑定相应的委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAsyncNodeResult, int32, Result);

/**
 * 
 */
UCLASS()
class TESTTHREAD_API UMyBlueprintAsyncActionBase : public UBlueprintAsyncActionBase
{
	GENERATED_BODY()
public:

	UPROPERTY(BlueprintAssignable)
	FAsyncNodeResult Success;

	UPROPERTY(BlueprintAssignable)
	FAsyncNodeResult Failed;

	FTimerHandle TimerHandle;

	//这个声明为static不知道是不是必须的
	//meta=(WorldContext = "WorldContestObject"))可以自动获取调用actor的world,用于间接获取世界上下文
	UFUNCTION(BlueprintCallable, meta=(WorldContext = "WorldContestObject"))
	static UMyBlueprintAsyncActionBase* WaitTickCounter(UObject* WorldContextObject, ATickTestActor* TickTestActor, int32 TargetCounter);
};

MyBluprintAsyncActionBase.cpp

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


#include "MyBlueprintAsyncActionBase.h"

UMyBlueprintAsyncActionBase* UMyBlueprintAsyncActionBase::WaitTickCounter(UObject* WorldContextObject,
	ATickTestActor* TickTestActor, int32 TargetCounter)
{
	//基类是一个Uobject,因此不需要使用智能指针来管理
	UMyBlueprintAsyncActionBase* Node = NewObject<UMyBlueprintAsyncActionBase>();

	auto Function = [Node,  WorldContextObject, TickTestActor, TargetCounter]()
	{
		if (IsValid(TickTestActor))
		{
			if (TickTestActor->Counter >= TargetCounter)
			{
				UE_LOG(LogTemp, Log, TEXT(__FUNCTION__"@%u wait TargetCounter(%d) success. Current Counter=[%d]."), __LINE__, TargetCounter, TickTestActor->Counter);
				Node->Success.Broadcast(TickTestActor->Counter);
				WorldContextObject->GetWorld()->GetTimerManager().ClearTimer(Node->TimerHandle);
			}
			else
			{
				UE_LOG(LogTemp, Log, TEXT(__FUNCTION__"@%u waiting TargetCounter(%d)... Current Counter=[%d]."), __LINE__, TargetCounter, TickTestActor->Counter);
			}
		}
		else
		{
			UE_LOG(LogTemp, Log, TEXT(__FUNCTION__"@%u wait fail. Actor is invalid."), __LINE__);
			Node->Failed.Broadcast(-1);
			WorldContextObject->GetWorld()->GetTimerManager().ClearTimer(Node->TimerHandle);
		}
	};

	WorldContextObject->GetWorld()->GetTimerManager().SetTimer(Node->TimerHandle, FTimerDelegate::CreateLambda(Function), 0.1f, true);
	UE_LOG(LogTemp, Log, TEXT(__FUNCTION__"@%u wait TargetCounter(%d) begin."), __LINE__, TargetCounter);
	return Node;
}

在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值