How is instantiating game objects and components done by Unity?

Hi everyone,

a lot of people have a lot of thoughts and opinions on when to use references to GameObjects, scriptable objects, static classes, Singletons etc. and I, too, have some practices I usually folllow. However, as my perspective on Game development with Unity is that of a C# programmer in non-game development, I sometimes wonder how things actually work.

I quickly understood that GameObjects are actually objects in the sense of C# that inherit from classes in the UnityEngine namespaces, as are components, the latter most importantly inheriting from the ubiquitous MonoBehaviour class. That means every component I attach to a game object will become an instance of the corresponding class at runtime and every game object will be an instance, too.

Now what I would like to understand is: When and how are these instances created? Note I mean instance in the OOP sense, not like instantiating a prefab (even though those are related). I especially wonder how the ubiquitous fields in my classes are set that I use to fill in from the inspector at edit time, typically like this:

public class Something : MonoBehaviour {
  public MyClass someStuff;
...

How do my components I dragged across the editor end up in the someStuff field of my Something’s instance? And what is the difference between that and doing a GetComponent() in Start() at runtime?

It is generally advised to not use GetComponent() in Update() which seems obvious to me. It seems, however, to be more controversial, if it is a good idea to avoid the usage of GetComponent() entirely. Often you can avoid it by using a field you can fill from the inspector, but that comes with other problems, so I wonder if it’s worth it - and why.

Please help me understand what happens inside the engine. If possible, I would appreciate links to the corresponding parts of the Unity reference source code. If there’s documentation or articles about it that are official and reliable, I’d appreciate those, too.

Thank you!

Edit: I already came across a link this blog post in another topic where someone asked something similar but it’s down. Apparently a lot of it comes down to serialization.

They’re created whenever you create them. This is true in runtime or edit time.

Anyway, you already answered your own question. It’s down to serialisation. Data persistence wouldn’t work any other way.

I should probably make more clear that I am talking about game objects I placed in my hierarchy in the editor and components I attached to them. Do I understand correctly that these are created at edit time, then serialized and loaded from serialized data at runtime? I would like to read more about that.

Yes that’s what I was referring to, though that same principle applies to pretty much every object that inherits directly or indirectly from UnityEngine.Object. Which is basically every kind of asset, alongside game objects and components.

Most if not all of that works on the C++ side of the engine, which isn’t really privy to anyone without enterprise source code access. Though most of us know that Unity instantiates uninitialised instances of our C# types, then populates said instances with the deserialised data, presumably through reflection.

This is why we cannot (or better put, should not) use constructors in any custom Monobehaviour or ScriptableObject derived types, and why we have to use specific factory methods such as AddComponent<T> or ScriptableObject.CreateInstance<T> to ensure our C# instances are correctly bound to their respective partner object on the native C++ side of the engine.

As a software developer I know you can appreciate what the Unity engine is doing. Frankly I’m impressed 99% of the time. It is a live system, running while we edit it. I think it could be interesting to see non-game app development done in a similar manner.

Might basic utility-type apps be developed using a scaled-back system?