FTasks in Unreal Engine 5
Brief overview and simple tests using FTasks in Unreal Engine 5

Game Engine
Unreal Engine 5.5.3
IDE
Rider 2024.3.5
Project Name
MyProject
OS
macOS Sequoia 15.3.1
Recently I was looking at FTasks in Unreal Engine 5 and they can be a great tool when programming in C++. The official Tasks System documentation can explain it much better than I can, but the Tasks System helps us "execute your gameplay code asynchronously". Similarly, in a previous post about saving and loading game data asynchronously `Async(EAsyncExecution::TaskGraphMainThread, {}) was used to not disrupt the game thread.
Leveraging Epic's FTask A-D example I wanted quickly implement that into an actor. I Simply created a new Unreal class called MyTasksActor
and populated it some functions that I'll use in BeginPlay()
.
MyTasksActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyTasksActor.generated.h"
UCLASS()
class MYPROJECT_API AMyTasksActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyTasksActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
UPROPERTY()
USceneComponent* MyRoot;
void FunctionA();
void FunctionB();
void FunctionC();
void FunctionD();
};
All the functions simply log out text, this is a very simple example. The actor will already have access to the FTask
class via UE::Tasks
. Instead of always having to write UE::Tasks::FTask
and UE::Tasks::Launch
, we can namespace UE:Tasks
so we only need to write FTask
and Launch
.
Similar to the example in the docs I create four FTask
variables, A-D, each calling their respective function along with having select prerequisites. If there is a prerequisite then the function can't launch until the prerequisite has completed.
Then I use the FTasks
's Wait
function to set a bool
indicating that all the functions have completed in the allowed timeframe. In this example I gave it a very generous three seconds. Below is the final .cpp
file and here is a link to it on GitHub.
MyTasksActor.cpp
#include "MyTasksActor.h"
// Sets default values
AMyTasksActor::AMyTasksActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
MyRoot = CreateDefaultSubobject<USceneComponent>(TEXT("MyRoot"));
#if WITH_EDITORONLY_DATA
MyRoot->bVisualizeComponent = true;
#endif
RootComponent = MyRoot;
}
// Called when the game starts or when spawned
void AMyTasksActor::BeginPlay()
{
Super::BeginPlay();
{
using namespace UE::Tasks;
FTask A = Launch(UE_SOURCE_LOCATION, [this]{ FunctionA(); });
FTask B = Launch(UE_SOURCE_LOCATION, [this]{ FunctionB(); }, A);
FTask C = Launch(UE_SOURCE_LOCATION, [this]{ FunctionC(); }, B);
FTask D = Launch(UE_SOURCE_LOCATION, [this]{ FunctionD(); }, Prerequisites(B, C));
constexpr int32 MyTime = 3;
bool bAllTasksComplete = D.Wait(FTimespan::FromSeconds(MyTime));
if (bAllTasksComplete)
{
UE_LOG(LogTemp, Warning, TEXT("All Tasks completed within %d seconds"), MyTime);
}
}
}
void AMyTasksActor::FunctionA()
{
UE_LOG(LogTemp, Warning, TEXT("Task A is complete!!!"));
}
void AMyTasksActor::FunctionB()
{
UE_LOG(LogTemp, Warning, TEXT("Task B is complete!!!"));
}
void AMyTasksActor::FunctionC()
{
UE_LOG(LogTemp, Warning, TEXT("Task C is complete!!!"));
}
void AMyTasksActor::FunctionD()
{
UE_LOG(LogTemp, Warning, TEXT("Task D is complete!!!"));
}
I hope to use FTasks
in the future, they look to be very helpful.

Harrison McGuire