Multi-threading in Unity with C# | Part I

What is a thread? Every program runs the main thread called the main pipeline. In multi-threading, we can change the program flow or add another flow. For instance: downloading assets, downloading maps, scene transitions, pathfinding, and multiplayer game server-client requests. In similar cases, when players start the game; we can continue downloading assets or calculate…

What is a thread?

Every program runs the main thread called the main pipeline. In multi-threading, we can change the program flow or add another flow. For instance: downloading assets, downloading maps, scene transitions, pathfinding, and multiplayer game server-client requests. In similar cases, when players start the game; we can continue downloading assets or calculate enemies’ paths without any effect on the player.

When I imagine multi-threading at Unity, I can list lots of things but first of all:

  • Slower than normal code process
  • Hard to debug
  • Complex code architecture
  • Easily get out of control

Most of these properties are bad, then why are we using multi-threading? There are specific problems that only (not only but easily) can be solved.

Unity officially does not support multi-threading. What does it mean? Every unity function, variables are only can be called in Unity main thread.

using UnityEngine;
using System.Threading;

public class Multithreading : MonoBehaviour
{
    [SerializeField] Transform player;
    private void Start() {
        Thread _thread = new Thread(CalculateDistance);
        _thread.Start();
    }

    void CalculateDistance(){
        float distance = Vector3.Distance(transform.position, player.position);
    }
}

Of course, we can write code like this but when we try to compile and run, we encounter this:

Unity does not allow the send data to another thread. It may look bad situation but actually good for us. Imagine that: if your custom thread could access unity main thread, meanwhile unity renders enemies based on positions and your thread change the enemy position unexpectedly. GameObject what should do in this situation?

Congrats! You had baby chaos!

We can prevent chaos by locking data. Locking data, ensure that data can not change another thread.

object FrontDoor = new object();


lock(FrontDoor){
	//Do something here
}

So, how to ensure make secure multi-threading? You have 3 different options for that.

  1. Coroutines.
  2. Calculate float variables at the custom thread and return the unity main thread.
  3. Unity Job System.

Unity already has a multi-threading system. If you look at it carefully, you can see that Unity.Physics running another thread. That’s why unity recommends that all the physics calculations should make at FixedUpdate() function event.

Another bad thing about multi-threading is the does not work at WebGL applications.

In part 2, I will explain the code side and how to do it.

Thanks for reading.

Source: Özge Kocaoglu