【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)
{
}