UE5 Multithreading with UBlueprintAsyncActionBase

Unreal Engine has multiple methods to implement Multithread and/or latent actions. In this tutorial, we will focus on using the UBlueprintAsyncActionBase. When we use this method, Unreal Engine will automatically create blueprint nodes for our latent/asynchronous functionality. 

 

As per the documentation, “BlueprintCallable factory functions for classes which inherit from UBlueprintAsyncActionBase will have a special blueprint node created for it”

“Factory Functions” means functions that can create and return an instance of our class.

We need to follow a few rules and steps to get this working and understand it. I’ll cover them below.

  1. Inherit From UBlueprintAsyncActionBase

First, we need to create a new class to wrap our asynchronous task. This class will contain any internal variables that we need to store and use while our task is running.

The class needs to inherit from UBlueprintAsyncActionBase

It’s worth noting that you can have one or more static factory functions that can create an instance of your class, particularly if their functionality is related. For example, “Save File” and “Load File” as asynchronous functions can both be hosted under the same class, but have their own unique way of initializing the class’s variables.

Take a look at the UAsyncActionHandleSaveGame implementation.

Using a static factory function as the constructor for our class is a convenient way to initialize and store any internal variables we need while the task is executing.

A Note On Garbage Garbage Collection

An important thing to keep in mind is that the class we created is a UObject, which means that it is subject to garbage collection. As our asynchronous task is essentially related functions,  executing within a UObject, we need to be aware that our task object will eventually be garbage collected if it doesn’t have a proper owner that is still alive.

 

To prevent this from happening prematurely, There are two ways:


We can manually call the “RegisterWithGameInstance()” and “SetReadyToDestroy()” functions that come with the class. Register will keep it from being garbage collected and SetReadyToDestroy() will mark it for garbage collection. I.e we are done using it.

 

Alternatively, we can use the “AddToRoot()” and “RemoveFromRoot()” functions, which allow us to control the lifetime of our task object. When are done doing our asynchronous task, we just need to “RemoveFromRoot()” and garbage collection will take care of deleting it for us.

  1. Create A Blueprint Callable Factory Function 

Next, we need to create a static function inside this class that is marked with the “BlueprintCallable” keyword. This function will act as a constructor for our class, allowing us to create and initialize an instance of the class from within a Blueprint graph.

 

The name we give to this function will determine what it is called within the Blueprint graph, so it’s important to choose a clear and descriptive name that accurately reflects what the function/task does.

				
					UCLASS()
class CUSTOM_API UCustomAsyncBase : public UBlueprintAsyncActionBase
{
	GENERATED_BODY()


public:

    UFUNCTION(BlueprintCallable, Category=Asyncs)
	UCustomAsyncBase* MyCustomAsynFunc()

};
				
			
  1. Set BlueprintInternalUseOnly to true

When we mark our factory function as “BlueprintCallable“, the engine will automatically create a node for our function within the Blueprint editor.

However, it’s important to note that if we inherit from UBlueprintAsyncActionBase, the engine will also create a node for the factory function of that class. This means that we may end up with two nodes with the same name in the editor.

 

To avoid this, we can add the meta tag “BlueprintInternalUseOnly = true” to our factory function. This tells the engine that our function is intended for internal use only and should not be exposed directly in the Blueprint graph. This means that we can disable the creation of the first node triggered by “BlueprintCallable” and only leave the one triggered by the UBlueprintAsyncActionBase class.

				
					UCLASS()
class CUSTOM_API UCustomAsyncBase : public UBlueprintAsyncActionBase
{
	GENERATED_BODY()


public:

    UFUNCTION(BlueprintCallable, Category=Asyncs,meta=(BlueprintInternalUseOnly="true))
	UCustomAsyncBase* MyCustomAsynFunc()

};
				
			

To Be Continued....
Keep Checking for more content.

5/5

Welcome to our audio and rhythm plugins collection! With MidiEngine, you can easily import MIDI files and use midi events to create engaging rhythm gameplay or enhance your videos.

4.5/5

Plugin that helps add UMG Widgets to Level Sequences for Text Layers, Movie Titles, 2D layers and more… directly within sequencer. Cross platform.

5/5

Let your end users Split And Resize The UI at runtime. Perfect for both games and Applications.

Consider investing in some of our plugins. They might save you some time.  Also helps supports these tutorials.

Instantly get access to our plugins like Blender Curves Importer and UMG Cinematics and more when  you support us on Patreon!

 Join Us On Discord For More Daily Tips!