Home Using C++ Timers in Unreal Engine
Post
Cancel

Using C++ Timers in Unreal Engine

The most straightforward way to use timers in C++ is to declare a UFUNCTION and a FTimerHandle in your class

1
2
3
4
UFUNCTION()
void HandleTimerExpired();

FTimerHandle MyHandle;

and starting the timer with the registered callback function from anywhere in your code, like so:

1
GetWorld()->GetTimerManager().SetTimer(MyHandle, this, &ThisClass::HandleTimerExpired, Seconds, bLoop);

In a lot of cases the above example is already getting the job done, but there is a big limitation: The specified callback function must be a void function with no input parameters.

So how does one call a function that has input parameters via a timer?

1
2
UFUNCTION()
void HandleTimerExpired(bool bInputFlag, int32 InputValue);

In that case we can create a FTimerDelegate as UObject-based member function delegate and pass our parameters directly when creating the delegate. In the SetTimer call we now use our FTimerDelegate:

1
2
3
FTimerDelegate MyDelegate = FTimerDelegate::CreateUObject(this, &ThisClass::HandleTimerExpired, true, 10);

GetWorld()->GetTimerManager().SetTimer(MyHandle, MyDelegate, Seconds, bLoop);

So far so good. That still leaves the question of how to call a function with return type via timer?

1
2
UFUNCTION()
bool TryHandleTimerExpired();

FTimerDelegate doesn’t allow a return type, but we can work around this limitation with the help of a lambda. The general syntax for lambda functions in C++ follows the pattern [ captures ] ( params ) { body } —check cpp reference to learn more.

Here is a simple example of creating a FTimerDelegate from a lambda function that wraps our callback function:

1
2
3
4
5
6
7
8
9
10
FTimerDelegate MyDelegate = FTimerDelegate::CreateLambda( [this] ()
  {
      if (TryHandleTimerExpired()) 
      {
        // Do even more stuff if function returns true.
      }
  });

GetWorld()->GetTimerManager().SetTimer(MyHandle, MyDelegate, Seconds, bLoop);

There are even more ways to create a FTimerDelegate but those three simple examples are covering the most common use cases already.

Don’t forget to clear your timer handle during EndPlay to not leave any timers running if the object gets destroyed:

1
GetWorld()->GetTimerManager().ClearTimer(MyHandle);
This post is licensed under CC BY 4.0 by the author.