Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Unity what exactly is going on when I implement Update(), and other messages from 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'm amusing this is something going on behind the scenes?

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.

like image 516
Adam LeBlanc Avatar asked May 13 '15 17:05

Adam LeBlanc


2 Answers

One thing to remember is that the Unity team didn't necessarily design their scripting API (including the MonoBehaviour class) to promote good software development principles; they designed it for accessibility and ease of use (especially for non-programmers). This is slowly changing, but there's still a lot of inertia toward "what's easy" instead of "what's right."

That said, let's get to answering your question. Regarding "messages," check out what the docs say about Component.SendMessage:

Calls the method named methodName on every MonoBehaviour in this game object.

When you look at the documentation for, say, Collider and see the methods listed under the Messages section, that's an indication that if you implement those methods, they will be called (via SendMessage) in response to some event or action (OnCollisionEnter, for example, "is called when this collider/rigidbody has begun touching another rigidbody/collider."). I might have implemented them as event delegates, but the Unity team chose to implement their own messaging system using strings, again, in the name of "ease of use."

To that same effect, if you walk up the inheritance chain for a MonoBehaviour class, you'll notice that nowhere in the chain do you actually find declared methods named Update or Start or the other lifecycle events of your scripts. Unity is treating these as magic methods and calling them (again via SendMessage, it appears) if they exist in the implementing class. That's why it doesn't matter if your Update method is public or protected or even private... it'll still get called.

like image 143
Derek Stobbe Avatar answered Sep 21 '22 18:09

Derek Stobbe


The way they are doing it under the hood is by using reflection to get the method that matches, which is why

 void update(){}
 void Update(bool inVariable){}

won't get called and

void Update() {}

will

They look for a method that matches both name and parameter signature (in this case does not take in an argument). The first two have an issue with either capitalization or parameter input.

By using reflection you dont need to have a function be public in order to call it but it doesn't hurt it if it is.

They use the same type thing for the message system, which is why you can call any function, though they limit to only taking in one variable with the message.

like image 24
Colton White Avatar answered Sep 24 '22 18:09

Colton White