I am new to Unity. I haven’t found any concrete info on this. I am a software engineer and instinctively assumed methods on MonoBehaviours can be called from any arbitrary thread, so have added thread safety code. Then I thought that if method calls all originate in some Update() method somewhere then they might be intrinsically serialised. The language in the editor strongly implies they aren’t concurrent by saying that scripts are “executed in order”, but that’s not exactly definitive.
Does Unity call all Update() methods in serial or with some concurrency?
They are called serially, always on the main thread. Indeed, it’s forbidden to call most Unity framework functions from anything other than the main thread.
Everything you mentioned is called Serially and is run in the main thread. Coroutines are just Update calls with variable time between calls, and who keep track of where they left off in code execution. They can break off in the middle of function whereas Update cannot.
FixedUpdate works just like Update, but with a different timing mechanism. Every time you pass control to Unity it renders the next frame. Then it goes through and calls all the Updates on all your objects one after the other in an order you don’t know (though this can be set, i think its a bad idea as it can lead to some confusing bugs if you start relying on lots of execution order dependencies). Update is passed the time since the last time update was called. (Time.deltaTime).
Once that is all done Unity checks if Time.deltaTime has surpassed your Physics Engines static frameRate. I believe by default its set to 50 fps. This is adjustable in the editor. So if your running at 50fps then everytime its been more than.02s since the last FixedUpdate it calls another one. If you running at 60 fps sometimes the physics engine will skip a frame, since its wiating for that .02 threshold.
This also means the opposite… if its been .04 seconds since the last Frame, you will get two FixedUpdate calls in between your regular Update as the physics engine catches up. There is absolutely no threading in a default Unity application. Everything is just being scheduled to be called and run serially.
There is absolutely no threading or concurrency of any kind with scripting under any circumstances or with any functions, aside from anything you specifically do yourself with System.Threading. There are a few async functions, but they’re still not on separate threads.
That’s correct. An infinite loop in any MonoBehaviour callback function — or anywhere else on the main thread — will lock up Unity (including locking up the editor itself, if you are playing your game within the editor).
To contribute to the pedantic party, user scripts can be multi-threaded, it’s just that a call/use of anything from the Unity API from a thread other than main is illegal, since Unity API is not thread safe.
It is as far as our (user) code is concerned. There may be other threads behind the scenes, doing who knows what, but all the MonoBehavior code (all of it) is called from the main thread. I don’t know how to be any clearer about it.
EDIT: And the editor itself also runs (at least primarily) on the main thread, because it is also built with the Unity API. This is why an infinite loop in your code will lock up the editor too.
For all intents and purposes your scripts are run in a single thread environment. You can spin up your own threads of course, but Unity only uses one thread to call your scripts.