【Unreal C++】⑤Timer(Delay)【UE4】
BPのDelayに相当する処理をするにはTimerを使うようです。
他に方法があればコメントで教えて頂けると幸いです。
Timerの開始
Timerを開始するにはFTimerManagerのSetTimer 関数を用います。
World->GetTimerManager().SetTimer(_TimerHandle,Callback,Rate,bLoop,FirstDelay);
引数 | 型 | 説明 |
_TimerHandle | FTimerHandle | Timerを管理する変数 |
Callback | TFunction | 呼びたい関数 |
Rate | float | 関数を何秒ごとに呼ぶか |
bLoop | bool | ループするかどうか |
FirstDelay | float | 最初に何秒待つか |
例(カウントタイマー)
hogeActor.h
UCLASS() class HOGEPROJECT_API AhogeActor : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AhogeActor(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; UFUNCTION() void Timer(); public: // Called every frame virtual void Tick(float DeltaTime) override; protected: UPROPERTY() UWorld* World; public: UPROPERTY() int PlayTime; };
hogeActor.cpp
void AhogeActor::BeginPlay() { World=GEngine->GameViewport->GetWorld(); FTimerHandle _TimerHandle; World->GetTimerManager().SetTimer(_TimerHandle, this, &AhogeActor::Timer,1.0f, true); } void AhogeActor::Timer() { PlayTime+=1; }
Timerの停止
Timerを停止するにはFTimerManagerのClearTimer 関数を用います。
また、もう一度同じTimerHadleでSetTimerを呼ぶと既存のものが破棄され、新しいものに置き換えられます。
ClearしたTimerHandleは新しいTimerを管理するために再利用することが出来ます。
World->GetTimerManager().ClearTimer(_TimerHandle);
引数 | 型 | 説明 |
_TimerHandle | FTimerHandle | Timerを管理する変数 |
Timerの一時停止
Timerによる関数呼び出しを一時的に実行しないようにするにはFTimerManagerのPauseTimer 関数を用います。
World->GetTimerManager().PauseTimer(_TimerHandle);
Timerの再開
一時停止したTimerを再開させるにはFTimerManagerのUnPauseTimer 関数を用います。
World->GetTimerManager().UnPauseTimer(SampleTimerHandle);
Timerが一時停止状態の確認
Timerが一時停止しているかどうかを確認するためにはFTimerManagerのIsTimerPaused 関数を用います。bool値がreturnされます。
if( World->GetTimerManager().IsTimerPaused(_TimerHandle) == true ) { }
反対にTimerがアクティブで一時停止していないことを確認するためにはFTimerManagerのIsTimerActive 関数を用います。bool値がreturnされます。
if( World->GetTimerManager().IsTimerActive(_TimerHandle) == true ) { }
追記
(2018.01.10)
↓のドキュメントではループありのタイマーをClearTimer関数でタイマーのクリアを行っています。
これは実質、タイマーの停止も担っています。
ここで1つ疑問に思ったのが、ループなしのタイマーでは自動的に停止するのでタイマーの停止を目的としたClearTimer関数の使用は必要無くなりますが、クリアを目的としたClearTimerが必要なのかということです。
docs.unrealengine.com
APIにはIsTimerActive関数やTimerExists関数がありますので、こちらを用いてループなしのタイマーが自動停止した後にまだタイマーが存在しているかを調べてみたいと思います。
docs.unrealengine.com
調査
いろいろ調べ方はあると思いますが、簡単な方法で実装します。
bLoopをfalseとしたSetTimer関数をBeginPlayで呼びます。
IsTimerActive関数やTimerExists関数をTickで呼びます。
TimerAct.h
#include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "Engine.h" #include "TimerAct.generated.h" UCLASS() class HOGEPROJECT_API ATimerAct : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties ATimerAct(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; protected: UWorld* World; FTimerHandle _TimerHandle; protected: UFUNCTION() void Process(); };
TimerAct.cpp
void ATimerAct::BeginPlay() { World=GEngine->GameViewport->GetWorld(); FTimerHandle _TimerHandle; World->GetTimerManager().SetTimer(_TimerHandle, this, &ATimerAct::HogeProcess,1.0f, false); //bLoop=false } void ATimerAct::Tick(float DeltaTime) { Super::Tick(DeltaTime); if (World->GetTimerManager().IsTimerActive(_TimerHandle)) { GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Green, "Active"); } if (World->GetTimerManager().TimerExists(_TimerHandle)) { GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Red, "Exist"); } } void ATimerAct::HogeProcess() { }
結果
プレイ開始からHogeProcessが呼ばれるまでタイマーが存在し、その後は自動的にクリアされ、存在しなくなっているようです。
※何か間違えがあればコメントよろしくお願い致します。