とあるゲームプログラマの挑戦と敗北の歴史

UE4とプログラミングとmayaとpythonとhtmlとマラソンを中心に情報を発信する元「技術ブログを目指すブログ」から再始動した毎日の日々を発信するブログです。

UE4:ディレイ系ノードの作り方(LatentAction)

以前も書いた記事と類似するが、
改めて指定条件が達成されるまで次に進まない
ディレイ系ノードの製作手順を記述しました。


以前の記事:マルチスレッドなディレイの製作手順
toncrimentan-w.hatenablog.com


いつも通りエディタからC++クラスを制作する
メニューバーのファイル>新規C++クラスを選択
f:id:toncrimentan_w:20210306011932p:plain


C++クラスを追加ウィンドウで
BlueprintFunctionLibraryを選択し
次へをクリック
f:id:toncrimentan_w:20210306012010p:plain


適当に名前をつけてクラスを作成をクリック
(ここではMyBlueprintFunctionLibraryとしている)
f:id:toncrimentan_w:20210306012248p:plain


すると無事エディタから
MyBlueprintFunctionLibrary.h と MyBlueprintFunctionLibrary.cpp
を作ることができます。
f:id:toncrimentan_w:20210306012353p:plain



それぞれ以下のコードを記述し
ビルドして実行
(ここではMyDelayノードとしています)
MyBlueprintFunctionLibrary.h)

#pragma once

#include "CoreMinimal.h"
#include "LatentActions.h"
#include "Engine/LatentActionManager.h"
#include "Kismet/BlueprintFunctionLibrary.h"

#include "MyBlueprintFunctionLibrary.generated.h"

UCLASS()
class LATENTTEST_API UMyBlueprintFunctionLibrary 
	: public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

	UFUNCTION(BlueprintCallable, meta=(Latent, WorldContext="WorldContextObject", LatentInfo="LatentInfo"))
	static void MyDelay(UObject* WorldContextObject, FLatentActionInfo LatentInfo);
	
};

class FMyDelayAction
	: public FPendingLatentAction
{
	FLatentActionInfo m_LatentInfo;
	float m_TotalSecond = 0.0f;
public :
	FMyDelayAction(const FLatentActionInfo& LatentInfo);
	virtual void UpdateOperation(FLatentResponse& Response) override;
};

MyBlueprintFunctionLibrary.cpp)

#include "MyBlueprintFunctionLibrary.h"

void UMyBlueprintFunctionLibrary::MyDelay(UObject* WorldContextObject, FLatentActionInfo LatentInfo)
{
	if(UWorld* World=GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
	{
		FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
		LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FMyDelayAction(LatentInfo));
	}
}

FMyDelayAction::FMyDelayAction(const FLatentActionInfo& LatentInfo)
	: m_LatentInfo(LatentInfo)
{
}

void FMyDelayAction::UpdateOperation(FLatentResponse& Response)
{
	m_TotalSecond += Response.ElapsedTime();
	UE_LOG(LogTemp, Log, TEXT("m_TotalSecond = %.2f"), m_TotalSecond);
	Response.FinishAndTriggerIf(3.0f<m_TotalSecond, m_LatentInfo.ExecutionFunction, m_LatentInfo.Linkage, m_LatentInfo.CallbackTarget);
}

LatentActionManager.AddNewAction()には
FPendingLatentActionを継承した自作LatentActionを指定します。

FMyDelayAction::UpdateOperation()では
Response.FinishAndTriggerIf()に次に進んでよいかどうかの有無を指定します



製作したMyDelayノードを実際に組み込みプレイ
f:id:toncrimentan_w:20210306013159p:plain



無事指定時間待ったのち次に進む
ディレイ系BPノードを作成することができました。
f:id:toncrimentan_w:20210306013333p:plain



この方法を利用すれば
指定時間の待ちだけではなく、指定条件が達成されるまでの待ち
も製作することができます。
こちらは非常に簡単なUE4のテクニックです。
必要に応じ、どんどん使いましょう。