Setting Timer in ExecuteTask()

I’m writing a task in C++ and I need to set a timer in ExecuteTask() which calls Beefy() after 4 seconds:

EBTNodeResult::Type UMyTask::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
  ...

MyPawn->StartWork();

// TODO:
// Set timer to call UMyTask::Beefy() after 4 seconds
// UMyTask::Beefy() needs OwnerComp to call FinishLatentTask() and MyPawn* to call MyPawn->FinishWork()


// Task not done yet!
return EBTNodeResult::InProgress;

}


void UMyTask::Beefy(UBehaviorTreeComponent& OwnerComp, APawn* MyPawn)
{
  MyPawn->FinishWork();

  // Task is done now. Return success.
  FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded);
}

Could anyone give a working code example that shows how this is usually done?

First you need to have world instance to access timer manager. You can get it from MyPawn.

Next you need to delere timer handle (FTimerHandle), without it you won’t be bale to control the timer after you start it. You can declere it in class, but if you don’t plan to control timer you can declere it locally.

Then you call SetTimer from Timer Manager, first parameter is handle you gonna use, 2nd is object on which function will be called, 3rd is a function pointer to function you want to call when time will be up, 4th amount time, 5th if timer should loop.

So it should like this:

FTimerHandle Handle;
MyPawn->()->GetTimerManager().SetTimer(Handle,this,&UMyTask::Beefy,4.0,false);

Study API refrence opf timer manager to see other function which you can use to control timer:

My trouble seems to be getting the 2 arguments into Beefy, particularly the OwnerComp. I have tried something like this as suggested by this answer:

FTimerHandle TimerHandle;
FTimerDelegate TimerDel;
TimerDel.BindUFunction(this, FName("Beefy"), OwnerComp, MyPawn);
()->GetTimerManager().SetTimer(TimerHandle, TimerDel, 4.0f, false);

But I get an error C2248: 'UBehaviorTreeComponent::UBehaviorTreeComponent': cannot access private member declared in class 'UBehaviorTreeComponent'. and OwnerComp has the red squiggly lines under it.

Could you show an example of calling FinishLatentTask() in Beefy so I could see the setup?

Thats because because it’s a reference, try sending pointer with &OwnerComp if it still complasins it’s private then you need public varable in class (which need to be pointer too)

Make sure that OwnerComp whatever it is is not gets deleted in 4.0s, otherwise you will end up with invalid pointer and sure crash. in worse scenerion you will need to use IsValidLowLevel

watch this