【UE C++】延迟执行方法 (Delay/异步执行)

本文介绍了如何在UnrealEngine中使用UEC++的延迟执行方法,包括DelayFinish函数的实现,以及FLatentActionInfo和UKismetSystemLibrary类在延迟动作调度中的作用。延迟动作可以在指定时间后或下一次Tick执行特定函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【UE C++】延迟执行方法 (Delay)

.h头文件

	// Delay回调方法  编写执行方法逻辑,如需要蓝图实现可添加BlueprintImplementableEvent宏定义
	UFUNCTION(BlueprintCallable)
	void DelayFinish();

.cpp文件

// Called when the game starts or when spawned
void XXX::BeginPlay()
{
	Super::BeginPlay();
	// LatentInfo, 
	// Param1 : Linkage 默认给0
	// Param2 : UUID 给个独一无二的编码即可  FMath::Rand()  或者给时间戳转Fstring + 类名 也可保证唯一性
	// Param3 : ExecutionFunction 要执行的方法名  用TEXT宏转一下
	// Param4 : CallbackTarget  回调传入的UObject目标 传this
	const FLatentActionInfo LatentInfo(0, FMath::Rand(), TEXT("DelayFinish"), this);
	// Delay  X秒后延迟后执行DelayFinish方法
	UKismetSystemLibrary::Delay(this, 25.0f, LatentInfo);
}

void XXX::DelayFinish()
{
	/// do something
}

源码参考

UKismetSystemLibrary

void UKismetSystemLibrary::Delay(const UObject* WorldContextObject, float Duration, FLatentActionInfo LatentInfo )
{
	if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
	{
		FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
		if (LatentActionManager.FindExistingAction<FDelayAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == NULL)
		{
			LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FDelayAction(Duration, LatentInfo));
		}
	}
}

void UKismetSystemLibrary::DelayUntilNextTick(const UObject* WorldContextObject, FLatentActionInfo LatentInfo)
{
	if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
	{
		FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
		if (LatentActionManager.FindExistingAction<FDelayAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == NULL)
		{
			LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FDelayUntilNextTickAction(LatentInfo));
		}
	}
}

// Delay execution by Duration seconds; Calling again before the delay has expired will reset the countdown to Duration.
void UKismetSystemLibrary::RetriggerableDelay(const UObject* WorldContextObject, float Duration, FLatentActionInfo LatentInfo)
{
	if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
	{
		FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
		FDelayAction* Action = LatentActionManager.FindExistingAction<FDelayAction>(LatentInfo.CallbackTarget, LatentInfo.UUID);
		if (Action == NULL)
		{
			LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FDelayAction(Duration, LatentInfo));
		}
		else
		{
			// Reset the existing delay to the new duration
			Action->TimeRemaining = Duration;
		}
	}
}

FLatentActionInfo

GENERATED_USTRUCT_BODY()

	/** The resume point within the function to execute */
	UPROPERTY(meta=(NeedsLatentFixup = true))
	int32 Linkage;

	/** the UUID for this action */ 
	UPROPERTY()
	int32 UUID;

	/** The function to execute. */ 
	UPROPERTY()
	FName ExecutionFunction;

	/** Object to execute the function on. */ 
	UPROPERTY(meta=(LatentCallbackTarget = true))
	TObjectPtr<UObject> CallbackTarget;

	FLatentActionInfo()
		: Linkage(INDEX_NONE)
		, UUID(INDEX_NONE)
		, ExecutionFunction(NAME_None)
		, CallbackTarget(NULL)
	{
	}

	FORCENOINLINE FLatentActionInfo(int32 InLinkage, int32 InUUID, const TCHAR* InFunctionName, UObject* InCallbackTarget)
		: Linkage(InLinkage)
		, UUID(InUUID)
		, ExecutionFunction(InFunctionName)
		, CallbackTarget(InCallbackTarget)
	{
	}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值