Create a Timer in Unreal Engine 5 Using C++

Timers are super helpful for triggering events in time intervals. We'll create a very simple TimerHandle that prints the screen every three seconds.

Unreal Engine 5 Quinn standing inside the C++ timer trigger box
Quinn inside the timer trigger

Software Versions: Unreal Engine 5.5.0 | Rider 2024.3

Project Name: MyProject

Create a new Unreal C++ actor class, I called mine MyActorTimer. I added some components for decoration, but most important is the FTimerHandle TimerHandle property, the TimerHandle will be doing most of the heavy lifting. Futhermore, I put in a UBoxCollision component to demonstrate the timer, on overlap the timer will start and the timer will be cleared when the players exits.

MyActorTimer.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActorTimer.generated.h"

class UBoxComponent;

UCLASS()
class MYPROJECT_API AMyActorTimer : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	AMyActorTimer();

	UPROPERTY(EditAnywhere)
	USceneComponent* Root;

	UPROPERTY(EditAnywhere)
	UBoxComponent* Box;

	UPROPERTY(EditAnywhere)
	FTimerHandle TimerHandle;

	UFUNCTION(BlueprintCallable)
	void StartTimer();

	UFUNCTION(BlueprintCallable)
	void StopTimer();

	UFUNCTION(BlueprintCallable)
	void TimerFunction();

	UFUNCTION()
	void OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

	UFUNCTION()
	void OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
};

Next, in the .cpp file we I start off by updating the constructor with a scene component and establishing the trigger box. Then, we can create our StartTimer and StopTimer functions by utilizing the GetWorldTimerManager. We can setup the timer by using SetTimer(), pass it the TimerHandler, indicate that it's under our current actor class, and then reference our function we want to trigger, in our case it's TimerFunction. Filling out the rest of the arguments, we're going to have it trigger after one second, we want to it to loop, and we don't want there to be a delay for the first event so we can set the last argument to 0.f.

GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyActorTimer::TimerFunction, 1.0f, true, 0.f);

Stoping the timer is very simple. We simply just call ClearTimer from the timer manager and pass it in our TimerHandle

GetWorldTimerManager().ClearTimer(TimerHandle);

Finally, we can fill out the rest of our .cpp file with overlap events and we are done. Once compiled we drag this new actor into our game world.

MyActorTimer.cpp

#include "MyActorTimer.h"
#include "Components/BoxComponent.h"

// Sets default values
AMyActorTimer::AMyActorTimer()
{
	Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
	Root->bVisualizeComponent = true;
	Root->SetVisibility(true);
	RootComponent = Root;

	Box = CreateDefaultSubobject<UBoxComponent>(TEXT("Box"));
	Box->SetHiddenInGame(false);
	Box->SetBoxExtent(FVector(128.f, 128.f, 128.f));
	Box->SetupAttachment(RootComponent);

	Box->OnComponentBeginOverlap.AddDynamic(this, &AMyActorTimer::OnBeginOverlap);
	Box->OnComponentEndOverlap.AddDynamic(this, &AMyActorTimer::OnEndOverlap);
}

void AMyActorTimer::StartTimer()
{
	GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyActorTimer::TimerFunction, 1.0f, true, 0.f);
}

void AMyActorTimer::StopTimer()
{
	GetWorldTimerManager().ClearTimer(TimerHandle);
}

void AMyActorTimer::TimerFunction()
{
	FString Message = FString::Printf(TEXT("Game Time Seconds: %f"), GetWorld()->GetTimeSeconds());
	
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Green, Message);
	}
}

void AMyActorTimer::OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	StartTimer();
}

void AMyActorTimer::OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	StopTimer();
}
Loading...