While I was creating my Procedural Terrain, I encountered a problem with performance, so I needed a solution for Multi-Threading that was powerful and easy, yet versatile and efficient.
After searching high and low all over the internet, I could never find the perfect solution, even the greatly priced Plugins didn’t cut it for me, so I set out to learn and code my own Plugin for Multi-Threading, hence, this post.
The Plugin is as simple and easy to use as it could be including only two functions, and yet it allows for great control and versatility, it allows any actor to implement it as it is an Implementable Interface, and doesn’t require any setup or fiddling with code, it doesn’t even require you to create custom classes or anything, you just add the interface to any actor, and it works right out of the bat.
Tutorial Section and Examples:
First off, download the Plugin here:
I will eventually make a Git repo at some time, mediafire will do for now
After downloading and extracting it, create a new C++ Project and copy the “Multi-Threading” folder to the “Plugins” folder of your Project.
Execute your Project and UE4 will ask if you want to recompile the Binaries of the Plugin, you must say “Yes”, and wait for it to finish.
After it finishes, you can copy the “Plugins\MultiThreadInterface” folder either to your working Project or to your Engine, and there you have it, the Plugin is compiled to your current version of the Engine, Installed and Ready to GO!
Inside your Actor Blueprint, Add the MTInterface:
The Interface will add two functions to your BP, one is an Event, and the other is a function that calls such Event.
The “Call Multi Threaded Function” function has a few settings to keep in mind:
First off, the Object reference must always be present, and it must be the Object which implements the Interface, a “Self” reference will work. However if you’re calling this function from another actor, the other actor must reference the actual actor which implements the Interface in order to work.
This function may be called at any time, whenever you want, however you want, as many times as you want, inside any logic whatsoever.
The “Async Exec Type” allows you to choose how you want the code to be executed, there are three possible options:
Task Graph will execute the code on any Thread that you choose right below, in the “Task Graph Type”, some threads execute the code in sync with the Game Thread, so you may want to choose Any Normal or Background thread for an Async execution.
Thread Pool will execute the code on any available thread from the thread pool, you do not need to choose which thread, it just picks an available one.
this two options are ideal for short and repetitive tasks, but not long and hauling tasks, for that we can use the New Thread option.
New Thread will create a new thread, however, this one cannot be spammed at will and will crash the Engine if doing so. to use New Thread you need to create a logic that controls the execution of the the function to happen only when the thread is available.
Such as in the following example:
When calling the function we check if the thread is available, if so, we set the variable “ThreadAvailable” to false immediately after.
Indside the “Multi THreaded Function” Event, we execute our code as normal, here i am just multiplying the indices of teh loops together, getting the square root of that and using it as input for a trace, this runs 50000 multiplications, square roots and traces in under 50 ms.
After the loop is completed we set a variable called “Calculation Done” to true.
In the Tick Event we keep checking for this variables to either Print the Result or change their state, it “Calculation Done” is true, we print the result and set “Thread Available” to true as well, and while the thread is not available we simply print the current state of the calculation.
For multiple multi-threaded functionality we can use a Switch in the “Multi THreaded Function” Event, such as:
We set the value of “Type Of Execution” right before calling the function, and inside the “Multi Threaded Function” Event, we use the variable on a switch to execute different tasks, we can always create a function with a local variable and store that value in it to be able to change it while the calculation is still running, and have multiple different caluclations running smultaneously (would only work with the Task Graph or Thread Pool).
We may also put the function on a Timer to keep calculating something as variables change in realtime, the implementation is really at your own leisure.
You can also join this Discord server for any assistance: