Delay function equivalent in C++

Hello guys.

I made a little game some time ago using Blueprints and I’d like to transform everything in C++.

I need to know how to build a Delay function in C++, the equivalent of this:

I read something about making a separate thread for that…
Any help?

UPDATE

I did this:

But is says that UnusedHandle is undefined.

1 Like

Hi gedamial,

In C++ you would use a timer: Gameplay Timers | Unreal Engine Documentation

When used like a delay node, the call might look like this:

FTimerHandle UnusedHandle;
GetWorldTimerManager().SetTimer(
	UnusedHandle, this, &AMyActor::TimerElapsed, TimerDelay, false);

This sets a non-looping timer that calls the AMyActor::TimerElapsed function after TimerDelay seconds.

13 Likes

C++ nativly does not support anything like this as CPU don’t have such function to execute code in delay, UE4 need to deal with that LatenActionManager, but it a lot more complicated to use them in C++ and it not well documented, look on code of those nodes if you want:

#L2891

It’s all to easier to just use timers insted that looks a way nicer in C++ :slight_smile: here docs for that

2 Likes

I spend too much time writeing anwsers >.>

1 Like

Sorry =D

no worries, it’s my fault ;p i leave my anwser at it has little diffrent info

You have to declare UnusedHandle in the OnPickup function before calling SetTimer.

FTimerHandle UnusedHandle;

In a looping timer you can store the handle as a class member and later use it to stop the timer. In this case you don’t need to keep a reference to the handle so it can be declared in the function scope.

1 Like

Move the code following the SetTimer call into the PickedDelay function if the goal is to execute those commands after a delay.

In order to add a timer in C++ you need a FTimerHandle in order to keep track of it. It is included in Actor.h, the syntax is as follows: ​

//Declare somewhere - Probably .h file
FTimerHandle TimerHandle;
​
//Somewhere in your .cpp file - NOT IN THE CONSTRUCTOR , BREAKPOINT WILL TRIGGER IF YOU DON'T DO OTHERWISE
GetWorldTimerManager().SetTimer(TimerHandle, this , &Method, DelayBetweenLoops , LoopTheTimer, FirstDelayInSeconds);
​ Obviously if LoopTheTimer is false , DelayBetweenLoops is going to be ignored. ​

Delay(FirstDelayInSeconds) -> &Method -> If LoopTheTimer == true -> Delay (DelayBetweenLoops) -> &Method -> ... //Till timer is stopped
​ You can have timers without a class and method reference: ​

()->GetTimerManager().SetTimer(TimerHandle, DelayBetweenLoops, LoopTheTimer, FirstDelayInSeconds);
​ No use case for LoopTheTimer == true :) You just need to check if it is active with ()->GetTimerManager().IsTimerActive(TimerHandle)

Thanks for the answer.
I updated the post. Check it out!

Thanks for the answer.
I updated the post. Check it out!

I get that error

Thanks :smiley: It works fine.

Will you explain me the purpose of the first, second and last parameter we pass to the SetTimer() function?

add a this parameter after UnusedHandle:

GetWorldTimerManager().SetTimer(UnusedHandle, this, &AHealth::PickedDelay, SpawnDelay, false);

1 Like

Glad you got it :slight_smile:

The header file documentation explains the inputs best

Sets a timer to call the given native function at a set interval. If a timer is already set for this delegate, it will update the current timer to the new parameters and reset its elapsed time to 0.

  • @param InOutHandle: Handle to identify this timer. If it is invalid when passed in it will be made into a valid handle.
  • @param InObj: Object to call the timer function on.
  • @param InTimerMethod: Method to call when timer fires.
  • @param InRate: The amount of time between set and firing. If <= 0.f, clears existing timers.
  • @param InbLoop: true to keep firing at Rate intervals, false to fire only once.
  • @param InFirstDelay: The time for the first iteration of a looping timer. If < 0.f InRate will be used.
1 Like

it’s not so true. this is a native C++ code:

 #include <thread>   

 std::this_thread::sleep_for(std::chrono::milliseconds(420)); //c++11

this however should not be used in UE4, because it will freeze the whole thread. UE4 has it’s own timers mechanism.

1 Like

I know it has been answered already couple of times but here’s a slightly better looking solution in your code (might not be very efficient tho). This way it’s so much easier to code delayed stuff.

// define somewhere
#define LATER_SECS(seconds, ...) \
    FTimerHandle __tempTimerHandle; \
    GetWorldTimerManager().SetTimer(__tempTimerHandle, FTimerDelegate().CreateLambda(__VA_ARGS__), seconds, false);

// usage
LATER_SECS(1.0f, [this, myCaptures]() {
    // my lambda function body
});
6 Likes

If I use a timer, is there any way to stop the function/event from ending until the timer ends?

1 Like

I’m just getting here from reading blueprints I wanna convert to c++. The KismetSystemLibrary has a delay function equivalent to the one in the blueprints, and that’s what I’m gonna use, I just thought I’d let you guys know if you’re searching for another solution

Delay function from kismet is not an “equivalent”, it is the blueprint Delay node.

Do not use it in c++, it won’t do what you expect.

Functions in c++ are like “functions” in blueprints (not events) - you cannot use delay (or latent actions) in them, because they have to execute and return a value immediately. Code execution is sequential.

Use timer or lambdas as mentioned above (preferably WeakLambda).

3 Likes