A method for Creating latent and async Blueprint nodes.
Livecoding doesn’t seem to always correctly reload these classes, keep that in mind.
Example
In short, blueprint async actions can be used by creating a class inheriting from the appropriate base. The class should have a static “factory” function which returns an instance of the class. UE will automatically generate an appropriate latent node for these functions.
The static function can take any parameters you need for the task, and should be used to initialize the task instance. The actual logic of the task should be triggered by overriding the Activate
function.
You should also add at least one delegate to the class. This should be called by your code once the async action finishes. These delegates show up as Exec pins in the latent node.
Below is an example for how to use blueprint async actions.
//h. file
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FMyDelegate);
UCLASS()
class MY_API UMyAsyncAction : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
//This function is used to create the async action from the BP graph.
//You can have more than one static function like this if you want.
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly=true))
static UMyAsyncAction* DoMyAsyncAction(AActor* Param);
//This delegate will appear as an Exec pin on the node.
//You can have many delegates, and delegates with parameters also.
UPROPERTY(BlueprintAssignable)
FMyDelegate Completed;
virtual void Activate() override;
protected:
//Props to store any state the async action requires
UPROPERTY()
AActor* Foobar;
};
//.cpp file
UMyAsyncAction* UMyAsyncAction::DoMyAsyncAction(AActor* Param)
{
//Create the task instance via NewObject
auto* Task = NewObject<UMyAsyncAction>();
//You can set props on the task or call functions on it
//to set up the task state
Task->Foobar = Param;
return Task;
}
void UMyAsyncAction::Activate()
{
//This function gets called when the async task is activated.
//You can put any logic here, remember to call your Completed
//delegate or other delegates you have to trigger the pins.
//...some code...
Foobar->DoSomething();
//...some code...
Completed.Broadcast();
}
Other important info
Depending on your code, you may need to call RegisterWithGameInstance
from your static factory function. This ensures the async node doesn’t get garbage collected if the blueprint which created it goes out of scope for any reason (such as in for-loops)
If you use RegisterWithGameInstance
, make sure to also call SetReadyToDestroy
when your async action has finished. This allows it to be garbage collected.