Timers are incredibly helpful for gameplay programming in Unreal Engine 4. The syntax is a little tricky if you’re not too familiar with C++ yet, this blog post will cover all the important features and syntax on how to use C++ timers effectively in your game.

For practical examples on timers check out my C++ Survival project, open-source on GitHub.

Note: This post was originally written in April ’15 after an C++ API change to timers for C++. Since then additional official documentation has gone up on Gameplay Timers with some additional info.

Set Timer

You set timers through the global timer manager which is available through GetWorld()->GetTimerManager() or the shorthand available in any Actor, GetWorldTimerManager() which returns the same timer manager. There are a couple of overloads (function variations) available to pass the function to execute, interval between ticks (if looped) and flag to set looping and the optional first delay. You can also set a timer to run on the next time by calling SetTimerForNextTick.

Code sample from SurvivalGame where we set a timer for a delayed explosion:

void ASBombActor::OnUsed(APawn* InstigatorPawn) { Super::OnUsed(InstigatorPawn); if (!bIsFuzeActive) { /* This will trigger the ActivateFuze() on the clients */ bIsFuzeActive = true; /* Repnotify does not trigger on the server, so call the function here directly. */ SimulateFuzeFX(); /* Activate the fuze to explode the bomb after several seconds */ GetWorld()->GetTimerManager().SetTimer(FuzeTimerHandle, this, &ASBombActor::OnExplode, MaxFuzeTime, false); } }

The handle is in the header file. Although you are not required to keep a reference to the handle, it’s recommended to do put this in your header to properly clear or pause your timer instance.

/* Handle to manage the timer */ FTimerHandle FuzeTimerHandle;

Binding Timer to Function

It’s important to make your function with UFUNCTION() macro in order to have it bind correctly with the timer. Otherwise an error will be thrown and can crash the engine. Your function will look something like this:

UFUNCTION() void OnExplode();

Clear Timer(s)

When destroying or deactivating objects, make sure you clear any active timers. There are two ways of dealing with timer removal.

void ASBombActor::EndPlay(const EEndPlayReason::Type EndPlayReason) { Super::EndPlay(EndPlayReason); // Ensure the fuze timer is cleared by using the timer handle GetWorld()->GetTimerManager().ClearTimer(FuzeTimerHandle); // Alternatively you can clear ALL timers that belong to this (Actor) instance. GetWorld()->GetTimerManager().ClearAllTimersForObject(this); }

Using SetTimer() on a Function with Parameters

It’s easy to pass in parameters into timer functions, the syntax is a little hidden, luckily this information was shared so I post it here for visibility. The following information I got from Orfeas on AnswerHub.

// CPP FILE FTimerDelegate TimerDel; FTimerHandle TimerHandle; // Params to pass into function once it ticks int32 MyInt = 10; float MyFloat = 20.f; //Binding the function with specific variables TimerDel.BindUFunction(this, FName("MyUsefulFunction"), MyInt, MyFloat); //Calling MyUsefulFunction after 5 seconds without looping GetWorldTimerManager().SetTimer(TimerHandle, TimerDel, 5.f, false); // HEADER FILE UFUNCTION() void MyUsefulFunction(int32 x, float y);

Timers are great for triggering delayed events and handling other time-based events that you may be inclined to put in your Tick() function instead.

Check out the API for FTimerManager API Documentation for more useful functions on timers. Including time remaining, finding the tick rate, active timers, pause/continue etc.

High Frequency Timers

It’s important to note that while you can run very high frequency timers, these do not actually run asynchronous or on a higher ‘real’ framerate than your game. Let’s say your game runs on 60 FPS and you have a timer on 0.005 looping interval. That’s about 200 times per second, internally it will still run approx. 200 times per second even at 60 fps! It’s important to realize though that this will execute multiple times in a loop, immediately after each other and NOT spaces out smoothly every 0.005.

It will run about 3 times per frame in a burst, which is just a waste of execution and could be done 1 time per frame with a higher DeltaTime to compensate for your calculations.

Learn C++!

Unreal Engine 4 Mastery: Create Multiplayer Games with C++Tom Looman, Epic GamesUnleash the power of C++ and Blueprint to develop Multiplayer Games with AI in this Epic Games-approved course.

References