• 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
1
Question by ronronmx · Oct 13, 2012 at 07:22 PM · monobehaviourstartupexecution order

Having OnEnable() defined changes execution order?!?

EDIT: After doing some more research I came across this discussion, which explains what I described below...what a mess! http://answers.unity3d.com/questions/217941/OnEnable-Awake-Start-order.html

Soooo I found out something interesting last night while trying to figure out why my LoadLevelAdditive() level's gameObjects where calling their Awake() and Start() functions after everything in my current scene.

My class was as follow:

 using UnityEngine;
 using System.Collections;
 
 public class ControlsManager : MonoBehaviour {
     
     // Singleton access
     private static ControlsManager _instance;
     public static ControlsManager Instance
     {
         get{ return _instance; }
     }
     
     public string[] controlPresetScenes;
     public GameObject[] controlPresets;
     
     
     #region Properties
     public GameObject ControlPreset01
     {
         get{ return controlPresets[0]; }
     }
     
     private GUI_Controls _guiControls;
     public GUI_Controls GUIControls
     {
         get
         {
             if( !_guiControls )
                 _guiControls = GameObject.FindWithTag("Controls").GetComponent<GUI_Controls>();
             
             return _guiControls; 
         }
     }
     #endregion
     
     
     void Awake( )
     {
         if( !this.enabled ) return;
         
         _instance = this;
         
         Application.LoadLevelAdditive( controlPresetScenes[0] );
         Debug.LogWarning("Loading HUD controls in " + this);  // Gets called right away
     }
     void Start ( ) 
     {
         _guiControls = GameObject.FindWithTag("Controls").GetComponent<GUI_Controls>();
         Debug.LogWarning("Storing HUD controls.", transform);  // Gets call after FixedUpdate()/Update() from current scene's gameObjects
     }
     
 }

Whit the code above, the Debug text "Loading HUD controls..." in Awake() gets called right away, but the line in Start() to GetComponent<>() always returns null, and the Debug text "Storing HUD controls..." is getting called AFTER FixedUpdate() and Update() functions for objects in the current scene...couldn't figure out why.

Then while trying ANYTHING i could think of, I added OnEnable() to the class:

 using UnityEngine;
 using System.Collections;
 
 public class ControlsManager : MonoBehaviour {
     
     // Singleton access
     private static ControlsManager _instance;
     public static ControlsManager Instance
     {
         get{ return _instance; }
     }
     
     public string[] controlPresetScenes;
     public GameObject[] controlPresets;
     
     
     #region Properties
     public GameObject ControlPreset01
     {
         get{ return controlPresets[0]; }
     }
     
     private GUI_Controls _guiControls;
     public GUI_Controls GUIControls
     {
         get
         {
             if( !_guiControls )
                 _guiControls = GameObject.FindWithTag("Controls").GetComponent<GUI_Controls>();
             
             return _guiControls; 
         }
     }
     #endregion
     
     
     // KEEP HERE OR GUI_CONTROLS WON'T EXECUTE RIGHT AWAY ???
     void OnEnable()
     {
         // For some reason having OnEnable() defined makes the execution order of the loaded scene objects a priority
     }
     
     
     void Awake( )
     {
         if( !this.enabled ) return;
         
         _instance = this;
         
         Application.LoadLevelAdditive( controlPresetScenes[0] );
         Debug.LogWarning("Loading HUD controls in " + this);  // Still gets called right away
     }
     void Start ( ) 
     {
         _guiControls = GameObject.FindWithTag("Controls").GetComponent<GUI_Controls>();
         Debug.LogWarning("Storing HUD controls.", transform);  // Now gets called right after Awake() above !?!
     }
     
 }

...and BOOM! Like magic, the call to GetComponent<>() in Start() is now returning my GUI_Controls class, AND the Debug text "Storing HUD controls..." is now appearing before FixedUpdate() and Update() functions, right after the Debug text "Loading HUD controls..." in Awake() (which still gets called at the same time).

Is this normal? I was taken by surprise, for sure! If anyone can "enlighten" me I would really appreciate it lol...

Thanks for your time guys!

Stephane

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

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by mikemvpi · Nov 06, 2013 at 02:43 PM

See this question

The answer from @Noisecrime says:

From the sound of it, this is the 'OnEnable' bug with script execution order. That is I suspect your 'framework' script does not have an OnEnable method in it, in which case for some odd reason it will get trumped in execution order by the scripts that do, despite any ordering you add to the script execution.

To fix this issue, simply add an OnEnable method to your framework script.

We also faced this issue today and it's looking like a total mess in Unity3D code..

Comment
Add comment · Show 3 · 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 ronronmx · Nov 06, 2013 at 10:55 PM 0
Share

$$anonymous$$ike, thanks a lot for the link to that other post! Were you able to fix it by doing the suggested change above?

avatar image mikemvpi · Nov 07, 2013 at 08:58 AM 0
Share

Stephane, in principle - yes. We added empty OnEnable() methods to all classes for that we had the Script Execution Order specified, and this seem to help.

I'm a bit worried about all other scripts that fall into "Default order" category and don't have the OnEnable() specified, but for now everything works fine.

avatar image ronronmx · Nov 11, 2013 at 10:26 PM 0
Share

Yeah I hear you, the "Default Order" seems to be a big ? mark...I hope this "bug" gets fixed someday, which of course means we'll probably have to change things around again!

Thanks for the help mike!

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

10 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

Related Questions

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

accessing vars of other script doesn't work 1 Answer

You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. 5 Answers

is there a monobehaviour method guaranteed to get called before I can call getter / setters for custom properties? 1 Answer

How to implement "PreUpdate" function 4 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