How easy is it to convert a function to an async one?

I’m a bit of a C++ fumbler, so bear with me here.

I’m looking to take a blueprint function like Rama’s one to write text to a file and make it run as an Async process. At the moment i’m using the engine to create some text files on the fly, and while it’s pretty quick on my SSD system i’ve noticed some serious clunkyness on a HDD based machine - the engine pauses momentarily while the task completes.

I’ve had a look at the documentation for FAsyncTask but it’s all a bit bewildering without any actual examples.

If anyone’s had any experience with this i’d love to have a go at this!

Thanks.

There are two ways to create async functions: creating latent functions and making functions that take dynamic delegates as parameters and execute them later.

Dynamic delegate parameters require less boilerplate code and allow async functionality to be used inside functions (by using the “create event” node), but since you need to store the delegate somewhere to call it later it’s better suited for object methods where you tell an object to do something and have it fire the callback later. Check the docs here to see how they work: Delegates | Unreal Engine Documentation

You basically declare your delegate signature and function like this:


DECLARE_DYNAMIC_DELEGATE_OneParam(FRemoteImageLoaderOnCompleteBP, UTexture2D*, Texture);

UFUNCTION(BlueprintCallable, Category = "Image")
static URemoteImageLoader* LoadImageFromURL(const FString& ImageUrl, FRemoteImageLoaderOnCompleteBP Callback);


Then when you are done, call the “Callback” that was passed to the function like this:


// "Texture" is a UTexture*
Callback.Execute(Texture);

The blueprint ends up looking like this:
Capture.jpg

Now, about latent functions. Those require you to create a class that derives from FPendingLatentAction to encapsulate all aspects of the “task” you are performing, so they are better suited for blueprint function library functions that can be called anywhere. The actions are added to the world’s LatentActionManager and are “ticked” so they can report whether they finished or not. They can also provide a human-readable status (it’s the text that shows up when you are watching a blueprint run live, like the delay node countdown). Just look at how Delay (UKismetSystemLibrary::Delay) and RetriggerableDelay are implemented (UKismetSystemLibrary::RetriggerableDelay) in KismetSystemLibrary and you should get a good idea how it works.

BTW, if you need to return a result it’s better to use delegates, since you can’t simply return a value from a latent function (it is possible to do it by using pointers to references, but it requires extra code to keep it safe).

1 Like

That’s great! To be clear though, in my example I want to write a text file with no impact on the rest of the engine - exactly like the async image loader - do you think it’ll work by just using the very same code, just integrated like this, or will I have to take further action within the actual function code to make it work asynchronously?

Thanks so much for the help. I’ve been blueprinting since v4.2 I think and have never really been able to satisfactorily make the leap into code, other than fiddling here and there. Time to step up i think!

You can use the in-engine async image downloader as an example or even the delay node. Do a global search for “UKismetSystemLibrary::Delay” and check how it works: you can just copy and paste the declaration, definition and the latentAction definitions into your own BlueprintFunctionLibrary class and rename it, then work from there.