Skip to content

Instantly share code, notes, and snippets.

@jeferwang
Last active November 5, 2022 12:45
Show Gist options
  • Save jeferwang/7d370678d7f5116ae646b8876b368a46 to your computer and use it in GitHub Desktop.
Save jeferwang/7d370678d7f5116ae646b8876b368a46 to your computer and use it in GitHub Desktop.
使用Latent实现多个执行引脚的蓝图节点(参考https://blog.csdn.net/flowersplug/article/details/80408493
#pragma once
#include "CoreMinimal.h"
#include "LatentBPL.generated.h"
UENUM()
enum class EDelayExecType:uint8
{
// 立即执行
ImmediateExec,
// 一半时间时执行
HalfExec,
// 时间结束时执行
CompleteExec,
};
UCLASS()
class TESTPROJECT_API ULatentBPL : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, meta=(ExpandEnumAsExecs="Exec", Latent, LatentInfo="LatentInfo", HidePin="WorldContextObject", DefaultToSelf="WorldContextObject"))
static void TwiceDelay(UObject* WorldContextObject, EDelayExecType& Exec, FLatentActionInfo LatentInfo, float Duration);
};
#include "LatentBPL.h"
#include "LatentActions.h"
class FTwiceDelayAction : public FPendingLatentAction
{
public:
float TotalTime = 0.0f;
float TimeRemaining = 0.0f;
FName ExecutionFunction;
int32 OutputLink;
FWeakObjectPtr CallbackTarget;
EDelayExecType& ExecRef;
bool bImmediateTriggered = false;
bool bHalfTriggered = false;
FTwiceDelayAction(float Duration, const FLatentActionInfo& LatentInfo, EDelayExecType& Exec)
: TotalTime(Duration),
TimeRemaining(Duration),
ExecutionFunction(LatentInfo.ExecutionFunction),
OutputLink(LatentInfo.Linkage),
CallbackTarget(LatentInfo.CallbackTarget),
ExecRef(Exec) {}
virtual void UpdateOperation(FLatentResponse& Response) override
{
TimeRemaining -= Response.ElapsedTime();
if (!bImmediateTriggered)
{
ExecRef = EDelayExecType::ImmediateExec;
Response.TriggerLink(ExecutionFunction, OutputLink, CallbackTarget);
bImmediateTriggered = true;
}
if (TimeRemaining < TotalTime / 2.0f && !bHalfTriggered)
{
ExecRef = EDelayExecType::HalfExec;
Response.TriggerLink(ExecutionFunction, OutputLink, CallbackTarget);
bHalfTriggered = true;
}
if (TimeRemaining <= 0.0f)
{
ExecRef = EDelayExecType::CompleteExec;
Response.TriggerLink(ExecutionFunction, OutputLink, CallbackTarget);
Response.DoneIf(TimeRemaining <= 0.0f);
}
}
};
void ULatentBPL::TwiceDelay(UObject* WorldContextObject, EDelayExecType& Exec, FLatentActionInfo LatentInfo, float Duration)
{
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
{
FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
if (LatentActionManager.FindExistingAction<FTwiceDelayAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == nullptr)
{
LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FTwiceDelayAction(Duration, LatentInfo, Exec));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment