C++ Delay? HOW?!

Hello, I’m new to Unreal Engine and I was hoping I can get some help.

I was wondering if anyone knows how to make a delay on Unreal Engine using C++. I already know about timers and delegates and how to get then to work, but I want to stop the current flow of execution until the delay time is over, similar to how delays work in Blueprints.

There is a function UKismetSystemLibrary::Delay() which is the function used in Blueprints for the delay node, however it’s doesn’t work the same way as Blueprints in C++. Passing in the correct parameters will give you a timer that calls a function after the time expires, but does NOT stop the flow of execution like it should in Blueprints.

I’ve done quite of bit of research on this topic and a majority of coders are using timers, which is better than delays, but I have a specific use for this delay in which timers are incapable of achieving. I’ve heard about using treads, but not really sure how to use them.

I appreciate any help I can get!

Delay doesn’t actually stop the flow of execution. It just continues to the next blueprint node after a time. C++ doesn’t work the same way. You can’t start and stop execution of C++ code like Blueprints.

Perhaps if you described what you’re trying to achieve. Almost sounds like you want to have a list of tasks that are executed at certain time intervals.

1 Like

@AlienRenders, thanks for your reply!
Yes your correct, code can’t stop execution. I think Unreal Engine calls a delay a latent function which just calls a function or continue executing code after a certain amount of time as you explained.

I’m trying to build an AI using behavior trees and tasks. I have this interface function that tells the enemy to play a certain animation and has an out parameter of type float which gives me the total duration of the animation. I want to use the animation duration to delay the task from exiting until the animation has finished playing.

I’m using the BTTask_Blackboard base for my C++ tasks, but I used the BTTask_BlueprintBase when I was experimenting with blueprints. I was able to have the behavior tree stay in the task until the animation was done playing using a delay node in blueprint, and I wanted to replicate that system using C++.

The reason why a timer won’t work is becuase I need to return something of type EBTNodeResult::Type. Functions that are binded to a timer need to have a void return type would doesn’t not for me.

I did some more research and found a function called FGenericPlatformProcess::Sleep which sleeps the current tread until some time before continuing executing code. It sounds exactly what I need or delay, but I’m not sure how to use it.

void CDelay::Execute(const UWorld *World, const float Time, FTimerDelegate const& InDelegate)
{
FTimerHandle TimerHandle;
World->GetTimerManager().SetTimer(TimerHandle, InDelegate, Time, false);
}

1 Like

@Ivan3z, thanks for the reply!
It looks like your using a timer, and I can’t really use a timer because functions that are binded to a timer need to be a void function. Also I can’t use functions because I want to delay a return call not a function call.

I’m using the BTTask_BlackboardBase and I’m using the UBTTaskNode::ExecuteTask function. This function require me the return a type of UBTTaskNode::Type similar to blueprint where we need to FinishExecute. Once I return something then the behavior tree will exit the task with a Failed or Succeeded, but I want to have the task wait until the animation finishes playing before returning. Currently, the animation is being spammed because the animation plays and then return Succeeded right after so the behavior tree exits the task and then reenters the task contantly. I want the task the play one animation at a time using a delay so the return doesn’t get called until the animation is finished playing. I can get the animation duration without any trouble, I just need help with the delay part.

Try this:

I have not tried it but it may help you
( Waiting for Task Completion)

 FTask TaskA = Launch(UE_SOURCE_LOCATION, 
    [] 
       { 
            FTask TaskB = Launch(UE_SOURCE_LOCATION, [] {}); 
            AddNested(TaskB);
       }
    );
    TaskA.Wait(); // returns only when both `TaskA` and `TaskB` are completed

bool bCompleted = Task.IsCompleted();

1 Like

@Ivan3z, thanks for the reply!
I’ve never heard of FTasks before so I don’t really know how to use it. I read the documentation you linked and I tried to set up a FTask, but I got complier errors saying that the FTask is an undeclared identifier. I searched the include for FTask and still nothing.

Here is the include I added:

#include "LocalizationCommandletExecution.h"

Here is the code that I added:

FTask Task = Launch(UE_SOURCE_LOCATION, []{});

Can you help with that? I also added the build module.

include “Tasks/Task.h”

All code samples assume using the namespace UE::Tasks for brevity.

UE::Tasks::FTask Task = UE::Tasks::Launch
(
	UE_SOURCE_LOCATION, [&](void)
	{
		return 123456.789f; // --> Whatever
	}
);
1 Like

@Ivan3z, thanks I got it to compile.

I tried using the task, but I couldn’t get the task the finished after the animation is done playing. I feel like I still need a delay because I can play the animation inside the task, but I need something to delay the task from completing. Thanks for the suggestion though!

use this:

FGenericPlatformProcess::Sleep()

if you put it inside of the task only block the stream inside of the task because it is like a thread.

1 Like

@Ivan3z, thanks for the reply and the help!

So here’s what I have:

#include "GenericPlatform/GenericPlatformProcess.h"
// Wrapped around an if statement which plays the animation which returns true
// or false if the animation was successfully played
// True-> run code below, False-> return EBTNodeResult::Failed

UE::Tasks::FTask Task = UE::Tasks::Launch
(
     UE_SOURCE_LOCATION, [&](void)
     {
          FGenericPlatformProcess::Sleep(AnimDuration);
     }
);

Task.Wait();
return EBTNodeResult::Succeeded; 

I tried to compile, but I’m getting an compile error saying that Sleep is not a member of “FGenericPlatformProcess.” This doesn’t make sense becuase the Sleep function is inside the “FGenericPlatformProcess” header file.

I tried using this:

FPlatformProcess::Sleep(AnimDuration);

Which compiles fine, but it sleeps the entire game.

Do you know why? Btw, thanks so much!

it was deprecated.

try this:

FGenericPlatformProcess::ConditionalSleep(TFunctionRef<bool()> Condition, float SleepTime = 0.0f);

1 Like

or this:

std::this_thread::sleep_for(std::chrono::milliseconds(x));
1 Like

@Ivan3z, thanks!

I tried to give both suggestions a try.
.

FGenericPlatformProcess::ConditionalSleep(TFunctionRef<bool()> Condition, float SleepTime = 0.0f);

I don’t really know how to make a TFunctionRef<bool()>. I did some research about it and I still couldn’t figure it out.
.
.

std::this_thread::sleep_for(std::chrono::milliseconds(x));

I was able to get this one to work, but there was an issue. Here’s my code:

UE::Tasks::FTask Task = UE::Tasks::Launch
(
     UE_SOURCE_LOCATION, [&](void)
     {
          std::this_thread::sleep_for (std::chrono::seconds(1));
     }
);

This one sleeps the entire game. Whenever this code ran is slept the game for one seconds and resumed after.

So the Task is not a thread then…

Use this:

bool bTaskCompleted = Task.Wait(FTimespan::FromMillisecond(100));

I think it’s your last chance.

You should read the documentation more carefully.

1 Like

@Ivan3z, thanks for all your help.
I already gave this a test a while ago when reading the Tasks system documentation and it doesn’t work. I’ve decided to just use a more messier way of coding this system by using other nodes in blueprints while casting and passing information between then.

I apologize if I wasted a lot of your time, this is a topic that I have not seen anyone be able to implement yet.
Thanks for all your help & suggestions! :pray:

you can still fire an event (delegate)… or replicate a variable and use Rep_Notify… check it out to see if it fits your logic!!

I don’t know if you know that functions can also return values by parameters

void Function(Type1 &Output1, Type2 *Output2)

pointers and references are magical!

A pleasure to help!!
Greetings!!

1 Like

You can actually trigger events from an animation… (Notify)… you can set it on the timeline… trigger one right at the end

1 Like

Yes, I agree pointers and references are like magic. :joy:

I’ve decided to wing the system by having a blackboard value that stores the duration of the animation which I passed as an out parameter on the interface function. Once I have the duration of the animation, I exit out of the task which then travels to a wait node in blueprint which will wait for the duration of the animation before completing the sequence.

Again thanks for all the help! It was interesting to learn about the more advanced stuff in Unreal Engine. Many paid courses and online videos online don’t even cover content like this.

Thanks! :+1:

1 Like

It was a pleasure!! Good luck with that!!

1 Like