Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by The Fluffy Prophet · May 13, 2015 at 06:34 PM · c#programming

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.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by fafase · May 13, 2015 at 08:56 PM

EDIT: 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. https://blogs.unity3d.com/2015/12/23/1k-update-calls/

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);
             updateList.Add(action);
             break;
         }
         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.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Lapinmalin · Apr 07, 2017 at 11:32 PM 0
Share

Finding this post just saved my sanity.

avatar image MD_Reptile Lapinmalin · Apr 07, 2017 at 11:32 PM 1
Share

I converted this answer to a comment. In the future, be sure to use the comment button (its kind of hidden under questions and answers) ins$$anonymous$$d of the big white box (which seems like the right thing to use, haha)

avatar image
2

Answer by FortisVenaliter · May 13, 2015 at 08:00 PM

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.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Make a game in C# 0 Answers

Getting nullreference error while using sendmessage 1 Answer

Enable secondary maps in simple shader 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges