I recently took a look into basic multithreading in Unity, to reduce the cost of the flow field algorithm in Bad North. Having got the main thread time on mobile down from 2.75ms to 0.25ms, I thought I’d write it up as a bit of a case study/tutorial on very basic threading in Unity. I’m hoping this will be accessible to anyone with a bit of Unity/C# scripting experience and an idea of what threading is, even if you’ve never written any threaded code before.
- I did not parallelise the algorithm itself. All I’ve done is push it to a different thread than the rest of the game.
- This is my first time threading anything with c#/.NET (I’m more experienced in c++), so there may well be some things that could be done better.
The Flow Field Algorithm
I’m not going to talk about the algorithm in detail, but as an overview the flow field is data spread across the navmesh that indicates:
- How many agents are nearby.
- How close they are.
- What direction they are in.
Each frame, every agent drops some “liquid” onto the flow field, which stacks up on the nearby vertices. This liquid then flows around the navmesh vertices and also “evaporates”. The effect is visualised by the blue / orange debug graphics on the gif below.
The following actions occur on to the flow field data
- Systems sample data from the field.
- Agents add data to the field.
- The propagation (or flow update) occurs.
This occurs in the following way in the main thread
Note that all of the thread diagrams in this post are simplified, and the horizontal axis (time) is not to scale.
Various systems/scripts read and write to the flow field throughout the frame (green arrows). Then during the flow update, a lot of reads and writes are done to the flow field. The flow update is is the significant costly part and that’s what we want to run on a separate thread. There are some implications of doing this, but we’ll worry about that later.
First let’s make a thread!