[Access Modifiers] Why aren't MonoBehaviour messages like Update() protected?

Just something I’ve been curious about for some time.

Why does Unity have us type void Update() instead of protected override void Update() as I would expect?

I also find it weird that I can change the access modifiers on those functions. Eg. changing Update() from a private function to a protected function is allowed.

I’m guessing Unity is using some kind of reflection to find the private Update() function and run it. I guess I don’t know why they didn’t just give MonoBehaviour messages a protected access modifier and be done with it. There must be a reason!

2 Likes

So something came up that made me wonder this again.

I found a bunch of Reset() functions in this project because someone (me) didn’t know that MonoBehaviour gets Reset() messages. Also reminds me of another bug that was caused by Main() getting called a lot too, which isn’t even in the documentation!

If these were protected functions of MonoBehaviour, the compiler would’ve told us this is a problem.

Why aren’t Reset() and Main() protected functions? I’m curious what the reason is!

I have a theory, I think during the build process Unity tracks what functions each MonoBehaviour has through reflection. The goal is to avoid calling a ton of empty virtual functions on every frame on every single MonoBehaviour.

I’m just grasping at straws. But I’m thinking now it’s a performance thing.

I don’t have the slightest clue about the subject, but i’ve already thought about the part i quoted from you alot. I always wondered whether they’re called or not, but rather just for my personal interest. :slight_smile:

Because they are messages, and when you write say Start function/method to your Monobehavior you implement a way to receive these messages. Calling a function has some overhead, and how little that may be can add up fairly quickly when you have thousands of behavior scripts on scene calling an empty Update and FixedUpdate or OnCollisionStay methods.

if you click the MonoBehavior class on visual studio and press Go To defintion you can actually see what methods it contains. Alterantively you can check the class reference.

1 Like

Yes, they use reflection to get at the methods to call.

Why? It’s so that if you don’t want to receive that message, you don’t implement the method, and the message isn’t sent. This is useful because it avoids calling an otherwise empty method. No method exists, so no operation cost is incurred.

You can put whatever access modifier you want on it because you’re implementing it yourself for the very first time.

3 Likes

@Vipsu and @lordofduct
Yes i noticed there are actually a lot of messages and that often crossed my mind when i added a new script. Thanks for clarification so far.
But does it happen during build as supposed by @GarthSmith or during import of the scripts? It seems to already happen during the import into Unity.

Unity is constantly compiling your scripts when it detects a change, but no messages are send before you actually hit play.
You can however call them trough Editor scripts yourself if you like

Does what happen? That the method gets registered?

It’s reflection, it happens when it needs to happen. The method is reflected out when it needs to be reflected out and called. That method once reflected may be held onto for future use in a hashtable of some sort so that the reflection doesn’t have to occur each time. This is all runtime though.

I know, that’s what i meant with importing, i was rather aiming at the reflection stuff. I suppose it happens during the import/compiling process instead of the building process, do you know that by any chance?
That would actually make more sense.

Frankly, they could have went with some interfaces for the method signature instead of invoking by reflection. Oh well.

2 Likes

Agreed, I don’t like the ‘message’ system as it currently stands in Unity.