Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading with Game Engines (Unity3D)?

I am using Unity3D and Mono to make a multiplayer online game. The language is C# script. I know that Unity is not thread safe. C# in Mono allows you to create a new thread using System.Threading. But Unity would forbid the new thread from modifying any of the GameObjects.

In my code I started a new thread to wait for a callback from some of my native C code (incorporated into Unity as Plugins). In this way, when the callback gets called it will be on the new thread, not Unity's main thread which has the authority to manipulate GameObjects. However, I want the GameObjects to be modified. What should I do? Should I use the main thread to poll the new thread? Or is there any better solution?

like image 597
Zening Qu Avatar asked Dec 27 '22 10:12

Zening Qu


1 Answers

There is more than one way to signal a main thread that data is available on a 2nd thread. Generally speaking, the first way might be to have the first thread "block" (wait) until the 2nd thread "signals"; however, without going into detail here this is not the approach you want to take, because blocking the main thread while you perform lengthy computations on your 2nd thread will make your game unresponsive at worst or jittery at best.

So this leaves the other approach which you brought up: polling. However often you feel necessary (once per frame, once every 60 frames), your main thread code (e.g. in a MonoBehaviour) will want to check on the status of the task in the 2nd thread. This could be via calling a method or checking a boolean value on an object "owned" by the 2nd thread. Via this approach, your task will indicate to the main thread polling whether things are "done" or "not done". Unity co-routines might be a useful mechanism for implementing your polling logic from the main thread.

However, you are not necessarily done yet. If your 2nd thread is going to repeatedly generate new data into the same variable or buffer, you have to also make sure your main thread will not read from a buffer that is being written by your 2nd thread to at the same time. For small amounts of data, you can use a double-buffering approach (two buffers/variables, one for reading, one for writing, which are swapped via pointer/reference exchange) when new data is ready; or you can use C# locks (but this can block your main thread with the side-effects described earlier).

Once your main thread has the data it needs, you can then of course proceed to modify your game objects from the main thread.

Note that your question is not all that specific to Unity. Most UI frameworks have this limitation (with good reason), and communication between threads is solved in similar ways in each instance.

like image 146
DuckMaestro Avatar answered Dec 30 '22 12:12

DuckMaestro