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?
Thanks!
~Adam
EDIT:
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.
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!
http://www.cs.arizona.edu/icon/oddsends/primes.htm
Rama
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.
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!
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.
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.
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.