I was looking for a way to multi-thread so my world generation could continue during runtime, but I cant find a single thing on multi-threading in UE4 anywhere. Can someone point me where to look or give me some tips on how to do it?


For anyone else wondering about this, a staff member on the UE4 Answerhub gave me this solution:

You probably want to use the tick task system, but I’m not sure if there are many docs on that yet though. You can look how the standard ActorComponent tick function is set up using FTickFunction. The key thing is that you will set bRunOnAnyThread to true, but you CANNOT do things like access/create/destroy UObjects safely from other threads.

Im helping him as what he is trying to do is something very similar to what im making here Log in with Atlassian account.
My voxel engine launches a “generator” thread when it finds that a regeneration of the voxel world is needed, such as at beginning of the game or when i start generating the voxels when i move, that starts calculating the vertex arrays and storing them into the chunk objects, when its done generating one chunk, it marks it as “finished”, and on the next Tick of the chunk it submits the vertex array to the rendering engine. Im using a std::thread there in a very very basic way

std::thread testthread(&VoxelWorldGenerator::UpdateField,this,fieldCenter); // launch generator thread, it then goes calling the generate vertex array functions in each block of the whole environment
testthread.detach(); // and then it leaves it alone, as we dont really need to modify that tread after that.

I wonder if something similar exists in UE4 libraries, or if we can just use std::vector from C++11 there.

Dear Victor,

Could you write a wiki tutorial on multi-threading?


when i figure out how the hell it works, be sure ill make a tutorial of it.

[FONT=Comic Sans MS]Multi-Threading Wiki Tutorial

My new Wiki tutorial on Multi-threading!

I am happy to announce I figured out how to use the UE4 Task Graph System to do multi-threading!

Here’s a video of my game calculating the first 50,000 prime numbers while I continue to play around in the main game thread!



**Comparing Results**

You can compare my in-game computed results displayed in the player console to this web page of the first 50,000 prime numbers!


sweet Rama that’s cool haha, could you make a plugin that lets me download your grasp of C++ directly to my mind ;)?

I was told by an Epic employee that the Task Graph system is only good for small workloads. Rendering chunks of voxels is probably not in the scope of what Task Graph can do.

Still its extremely useful, awesome tutorial!

well I was actually thinking about your example

You can do all the calculations in the task threads, and then send the final output data to the game thread, and the game thread can have a short timer, like 0.01 seconds, to actually check what data the other threads are returning and spawn / create the required objects using the pre-computed data.

As each chunk of data is processed in game thread it is removed by that 0.01 second timer so that it does not recreate the same meshes twice.

If you are doing lots of complicated calculations in advance and can just send final spawn / creation data back to the game thread that would work great!

Good luck!


Threading question. I’m getting a callback from Android which is not in the main game thread. The callback has access to my AActor. What’s the recommended way to get the main game thread so I can interact with AActors?

**** NOT in the main thread **** I have parameters from a callback that needs to go to the main thread…

*** Main Game Thread Over Here **** plz execute my code

It’s a little different than the wiki example, since I’m not spawning threads to do work. The work is already done and ready for the main thread.

The error:

D/UE4 ( 7738): Assertion failed: IsInGameThread() [File:C:\unreal\UnrealEngine\Engine\Source\Runtime\Engine\Private\TimerManager.cpp] [Line: 223]

You’ll need to invert that logic and have the main thread pull the data provided by the callback when it is actually in a state to handle Actor data (i.e.: during a tick). The easiest way to do this is with a centralized, unmanaged structure where you can queue up data for consumption. Put a FThreadSafeCounter on there, have the callback increment it when it is issued, then during actor tick, have it check if the counter is > 0 and consume the queued data if so.

Regarding your error, are you issuing timer delegates on a different thread? Because that won’t work, as you’ve found out. Whatever structure is issuing those timers could instead poll game time and manually call the delegates when the wait time elapses. I think UWord::TimeSeconds is thread safe, that’d be a good place to start.


That’s pretty much exactly what I implemented.

I used a Tick on my SDK actor to poll any available work that I shoved into lambda] functions from my threaded callbacks.

For whatever reason PrimaryActorTick.bCanEverTick = true; was needed to get the tick events to fire.

Thanks for the hints!

Yeah, there is a fair amount of overhead from managing ticking, so the default is not to do it. That’s a tricky surprise for newcomers trying to tick their actor that doesn’t derive from an already ticking class like Pawn.

Here’s the syntax I ended up going with.

void CustomCallbacksInitOuyaPlugin::OnFailure(int errorCode, const std::string& errorMessage)
__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, “OnFailure: errorCode=%d errorMessage=%s”, errorCode, errorMessage.c_str());

_resultErrorCode = errorCode;
_resultErrorMessage = errorMessage;

if (_actor)
		_actor->OnFailureInitOuyaPlugin.ExecuteIfBound(_resultErrorCode, _resultErrorMessage.c_str());


I used some static fields on some callback classes to keep things neat.

And then a vector of functions to execute in my update tick.

// Use the tick event to fire callbacks on the main game thread
virtual void Tick(float deltaSeconds) OVERRIDE;

// hold functions to execute in the main thread
std::vector<std::function<void()>> _mainThreadActions;

Works like a charm.