What exactly is going on when I implement Update(), and other messages in MonoBehaviour

I’m pretty new to C#, coming from a strong background in Java, python, and some “web” stuff. So I’m probably just missing some knowledge here, that hopefully somebody can fill in for me.

Going through the Unity Scripting API, I noticed a lot of methods, listed under “Messages”, which is my first point of confusion. What exactly is the difference between a “Message” and a “Method”, to me they seem like they are the same thing, but the terminology is throwing me off.

My second point of confusion, is that when I implement a “Message” like Update() in my derived classes, I don’t have to use the override keyword. Which is bugging me, because wouldn’t I just be hiding it? In which case, wouldn’t the update loop just know about MonoBehaviour and not my derived class, and call Update() in MonoBehaviour, instead of my class? This is throwing me for a loop.

I’ve been getting along really well with Unity, and C#, this is just a sticking point for me, where I feel like I’m missing some knowledge.

Basically because it’s not really using true .NET-style C#. It’s using Mono C# and treating it more like scripting than coding.

I was right there with you for the longest time. I even have a CSharpBehaviour class defined that creates virtual base functions for Update and Start that I use today. But a few months ago, I found out why they do it the way they do.

Basically, it’s for optimization. If the function doesn’t exist, then that function itself and the surrounding Unity code are never called. The easiest way to test this is to add a new empty component class, make 100,000 instances in a Unity window. If no functions are defined, overhead will be very low. Now add an OnGUI() function to the class and run it again. Even if nothing happens in that function, performance will be terrible.

So, Unity uses it almost like a preprocessor include/exclude system when compiling scripts, and only calls the functions that are defined, which would not be possible if they all them as override-able.

For those coming here, my answer below is no longer valid (or actually never was).
There was an old thread on Unity Forum on which a Unity dev would mentioned that reflection was used (and I thought he knew) but a more recent blog post cleared the problem.

How Update is called

No, Unity doesn’t use System.Reflection to find a magic method every time it needs to call one.
Instead, the first time a MonoBehaviour of a given type is accessed the underlying script is inspected through scripting runtime (either Mono or IL2CPP) whether it has any magic methods defined and this information is cached. If a MonoBehaviour has a specific method it is added to a proper list, for example if a script has Update method defined it is added to a list of scripts which need to be updated every frame.
During the game Unity just iterates through these lists and executes methods from it — that simple. Also, this is why it doesn’t matter if your Update method is public or private.

I’ll leave the answer for learning purpose but this is not how Unity works.

The reason why you do not hide the methods is because there are none to hide. Unity uses reflection in place of polymorphism.

So instead of declaring a whole bunch of those messages for any single MonoBehaviour, it checks if they are declared.

Assuming a scene is a container for game objects and a game object is a container for MonoBehaviour, each frame the scene takes each active object and run the messages, most likely Start is not done already, and the various updates. Other OnSomething are called on events (enabling, disabling, new scene or else) so they belong to another bag of methods.

If you have polymorphism, it means they are in MonoBehaviour and needs to be run even though they don’t exist in your own class inheriting from it. Despite the tiny overhead, it is still there.

Using reflection, you just add to a list the method that you find in the script:

internal List<Action>updateList = new List<Action>();
public void AddComponent<T>(){
    Type baseType = typeof(T);
    while ((baseType.ToString() != "MonoBehaviour") || baseType == null){
        update = baseType.GetMethod("Update", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
        if (update != null){
            Action action= (Action)Delegate.CreateDelegate(typeof(Action), this, update);
        baseType = baseType.BaseType;

See now, only if the method is found via GetMethod then it is added to the list. That list is used later on by the scene to iterate through all updates attached to that GameObject. It also goes up the inheritance hierarchy to make sure to find that private Update on a base class.

The list will only contain Update that were declared in custom scripts and then saving resources.

Keep in mind I do not work at Unity and then do not know what is actually going on. Most likely this is done in C++ but you should get the idea.