Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
2
Question by Xarbrough · Sep 04, 2015 at 01:26 PM · c#startawakeonenable

Does the access modifier of Start(), Awake(), OnEnable() make a difference to Unity?

Does it make any difference to Unity if I use public void OnEnable() vs private void OnEnable()?

Is there a general practice you can recommend? When subclassing MonoBehaviours it probably makes sense to use protected or even protected virtual. However, I often see thoses methods being exposed publicly. This only spoils my auto-completion, since I won't ever call those methods explicitly, right? Or is there a performance benefit because Unity searches faster for public methods?

Thanks!

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

3 Replies

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

Answer by valyard · Sep 05, 2015 at 07:53 PM

While @BMayne is mostly correct, it's worth noting that Unity doesn't use reflection nor to get these functions nor to execute them at runtime. Since it uses Mono virtual machine, Unity from C++ code can ask it what methods a class has.

So internal logic is like this:

  • Get all methods from the whole class hierarchy down to UnityEngine.Object.

  • Filter instance methods.

  • Find built-in methods like Awake, Start, Update, etc... and put them in a cache.

  • For all instances of a class add pointers to their Awake, Start, Update, etc... methods to corresponding managers which call these methods when needed.

Usually you don't want these methods public, having them non-public doesn't matter performance wise. You can have these methods protected though if you want to set up an inheritance chain.

But in this case you must be really sure what you are doing, since if you have for example a custom MyMonoBehaviour class derived from MonoBehaviour with all these methods (Awake, Start, Update, etc...) declared as protected virtual, ALL these methods for ALL instances of classes derived from it will be registered with aforementioned managers internally and be called each frame (in this case I'm talking about Update). Though individually these empty methods are fast, having hundreds of them may slow things down.

Comment
Add comment · Show 8 · 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 Ghopper21 · Dec 31, 2015 at 02:21 AM 1
Share

I the public/private question isn't applicable in actual technical sense, due to the way these methods accessed in a special way from within the runtime.

However, I'm torn about whether Awake etc. "should" be public from a style/philosophical point of view.

The fact is, the methods are being called from outside the class hierarchy -- that's the common sense definition of public, right?

Curious what you think about this stylistic/philosophical point?

avatar image Bunny83 Ghopper21 · Dec 31, 2015 at 04:54 AM 0
Share

Well, that purely depends on how you declare the methods from an OOP point of view. For example if you declare your methods as non virtual methods there's no point in using any access modifier than private. The methods are only relevant to the class itself since they are called only directly from the runtime.

However if you want to use some inheritance / base classes you might want to declare them as virtual. In that case "protected" would be appropriate. "public" is actually never appropriate since those methods are never ment to be called manually from another class.

avatar image Ghopper21 Bunny83 · Dec 31, 2015 at 05:02 AM 0
Share

Sure, but private or even protected doesn't feel right (again, just stylistically/philosophically speaking) because those aren't meant to be called by the runtime either, really. Unity's runtime basically breaks the semantics of private/protected here. That's why I wonder if public is actually closer to the spirit of what's actually happening. These methods ARE going to be accessed outside of the class -- i.e. by Unity's runtime (albeit via a completely different mechanism nothing to do with public/private/protected).

avatar image Owen-Reynolds Ghopper21 · Dec 31, 2015 at 05:35 AM 0
Share

Clearly the correct style is to just write void Start(), with no explicit access modifier. Because that's the way Unity does it. I$$anonymous$$HO, that's the definition of Style.

If you start writing void public Start(), or even the redundant void private Start(), it will stand out -- people will waste time wondering why you had to change it from the usual way.

avatar image Ghopper21 Owen-Reynolds · Dec 31, 2015 at 05:41 AM 0
Share

I agree this is Unity's style. What I'm really asking is if Unity's style is really "right". I've always followed it. But I do suspect it wasn't really a good style choice by Unity for the reasons noted.

avatar image Bunny83 Ghopper21 · Dec 31, 2015 at 06:44 AM 0
Share

No, those methods aren't accessed from outside the class. $$anonymous$$eep in $$anonymous$$d that a $$anonymous$$onoBehaviour component consists of a native and a managed part. You only see / edit the managed part. The native and manage part of the class are communicating in both directions. For example when you read the position property of the Transform class you actually call a hidden external method in the native part of the class which returns the position which is also stored in the native part.

The callback methods like Start, Awake, Update, ... are actually callbacks which are called from the native C++ side.

Some people try to view their scripts as plain C# but Unity is't written in C#. $$anonymous$$ono is just the used scripting engine. When you design components you should focus on the usage within it's domain inside Unity. As such you never want to directly call those methods from another class. They are simply callback methods from the engine and only relevant to the class itself.

If someone else is using your class as a blackbox they shouldn't see those methods since they belong to the component itself. You could imagine them like you implicitly registered them to some kind of manager. So just like there's a line like this in the constructor:

 manager.RegisterStartCallback(Start);

In such a case you would make Start private since it's only used internally by the class itself. Based on basic OOP encapsulation rules those methods should be private. $$anonymous$$aking something private / protected / public has nothing to do with a "style". The decision should be only based on the usage of those things. A style is a different way of structuring code without actually changing anything. Things like where you place your opening brackets, how you split long lines, na$$anonymous$$g conventions, in which cases you use "switch" ins$$anonymous$$d of "else if", when you use while / for / do-while ...

avatar image Ghopper21 Bunny83 · Jan 03, 2016 at 09:26 PM 0
Share

I see it differently. Sure, they are being called from the C++ side, that's not the question. The question is whether that call from Unity's game loop is closer to the "outside" or "inside" semantics. Seems closer to outside to me.

Show more comments
avatar image
1

Answer by BMayne · Sep 04, 2015 at 05:13 PM

Hey there,

Here is an example of what Unity is most likely doing behind the scenes.

         typeof(MonoBehaviour).GetField("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

As you can see it searches for the function by name and then if it is public or non public (internal, protected, or private). When you change the access modifier it will have no effect on Unity's ability to grab it.

Cheers,

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
avatar image
0

Answer by Owen-Reynolds · Sep 04, 2015 at 04:48 PM

I'm going to guess it won't matter, but check whether any of this is wrong:

I assumed C# had some bizarre rule where, maybe a superclass or something could have subclasses default to public or something. But, of course, no. Start is private, and is being found using Reflection. That a known trick (why!?)

I think Reflection can specify only finding Private or Public members, which probably runs faster. But Unity isn't doing that. public Start() works just fine. There doesn't seem to be any other way to use Reflection besides "limit to only these sorts of things."

And, Reflection still gets a reference, right? It's not like it's doing it every frame for Update. I'm wondering if it doesn't do it once for each class, even, not each instance in the class. So the whole thing is just a minimal amount of work at start-up (maybe Instantiate, maybe not.) So falls under the usual "don't bother -- can't possibly save enough to matter" optimization rule.

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

32 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Initialising List array for use in a custom Editor 1 Answer

Reliable way to detect when the game starts playing on a ScriptableObject? 1 Answer

Class c = new Class() okay in class body? 1 Answer

Execution Order of Scripts - Awake and OnEnable 1 Answer

Multiple Cars not working 1 Answer


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