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
21
Question by sebas77 · Feb 16, 2012 at 07:17 PM · startawakeonenable

OnEnable, Awake, Start order

I use a "framework" class that is set to run before all the other scripts (-300). This class has an Awake method. I also use another normal monobehaviour which defines the OnEnable method.

Once the application runs, the OnEnable of the second monobehaviour is called before the awake of the framework class. Is this the intended behaviour?

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

8 Replies

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

Answer by Wolfram · Jun 27, 2012 at 03:38 PM

It's rather complicated.

[

Update 5.1.1: I didn't re-test everything, but here is what seems to be fixed/different in both 5.x and 4.x (tested 5.1 and 4.6), as opposed to 3.5:

  • The bug that the user-defined execution order is ignored if one (but not all) script has an "OnEnable()" function (=see "EDIT3" below) seems to be fixed.

  • OnLevelWasLoaded() is no longer called before Awake(), and always after OnEnable()

  • The execution order of OnLevelWasLoaded() is still arbitrary and cannot be user-defined

  • OnEnable() is no longer called in successive levels if DontDestroyOnLoad is active.

]

A simple test with 3.5.2 revealed, most concurrent functions (well, at least the ones I tested: Awake, Start, OnEnable, FixedUpdate/Update/LateUpdate) abide by the execution order defined for the scripts. The execution order of OnLevelWasLoaded is not affected by that, and therefore cannot be influenced by the user. This could be considered a bug.

The order of the four methods of a script related to initialization is always:

  • Awake()

  • OnEnable()

  • OnLevelWasLoaded() // (only on scene changes)

  • Start()

However, if your script was disabled in the first place(via Script.enabled=false), this order changes to:

  • OnLevelWasLoaded() // is now called first, before Awake()! (only on scene changes)

  • Awake()

  • [OnEnable()/Start() are not executed until the script is actually enabled]

In addition, note that Awake() and OnEnable() calls are connected/interleaved. Meaning, assuming a particular, user-defined execution order A and B with A*<*B,

  • each individual script of type A will execute its Awake(), immediately! followed by its OnEnabled()

  • then all scripts of type B will do the same

  • then all OnLevelWasLoaded() will be executed, in a (presumably) fixed but unpredictable order (assuming this scene was freshly loaded - otherwise this step is skipped completely)

  • then all Start() will be executed, in the order A,B

In particular, this means that OnEnable() of type A will be executed before Awake() of type B, while OnEnable() of type B will be executed after Awake() of type A. This overview explains it more clearly:

  • Awake() of Type A, instance 1

  • OnEnable() of Type A, instance 1

  • Awake() of Type A, instance 2 // order of instances cannot be influenced

  • OnEnable() of Type A, instance 2 // order of instances cannot be influenced

  • Awake() of Type B

  • OnEnable() of Type B

  • OnLevelWasLoaded() of Type ? // order cannot be influenced

  • OnLevelWasLoaded() of Type ? // order cannot be influenced

  • Start() of Type A

  • Start() of Type B

EDIT: Hm, this is a total mess. If DontDestroyOnLoad() is activated for such a script, this will get even more complicated, and the order changes yet again to:

  • [Awake() is never called again, only the very first time]

  • OnEnable()

  • OnLevelWasLoaded() // as opposed to being called before OnEnable(), when DontDestroyOnLoad() is not activated

  • [Start() is never called again, only the very first time]

EDIT2: In addition, when DontDestroyOnLoad() is active, the user-defined execution order is no longer abided by!, neither by OnEnable(), nor by OnLevelWasLoaded().

EDIT3: WAH! I'm gonna stop testing now, this is a neverending story... As @Noisecrime noticed, there is actually another bug, where user-defined execution order is overriden if the script has an OnEnable() function!

Script A has OnEnable, Script B has not:

  • Awake() of Type A

  • OnEnable() of Type A

  • Awake() of Type B

Script B has OnEnable, Script A has not:

  • Awake() of Type B

  • OnEnable() of Type B

  • Awake() of Type A // after Type B!

Comment
Add comment · Show 9 · 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 yoyo · Dec 21, 2012 at 12:28 AM 6
Share

And note that Awake is called even on a disabled component, but not if the game object it is attached to is inactive. (This may or may not seem obvious, it wasn't to me ... ;-)

avatar image yoyo · Jul 11, 2013 at 05:48 PM 4
Share

For added fun, in the editor environment, OnDrawGizmos may be called before Awake ... so make sure your gizmo code checks for uninitialized data.

avatar image myfunkyside · Jul 25, 2014 at 02:08 AM 2
Share

I don't have enough thumbs for this answer

avatar image StarWeaver · Jul 25, 2014 at 04:33 AM 3
Share

Is this all still valid, +1.0 versions and 2 years later?

avatar image meat5000 ♦ · Jul 02, 2015 at 01:12 PM 0
Share

Glad to see you are still on this @Wolfram

Show more comments
avatar image
5

Answer by Noise crime · Jun 27, 2012 at 02:08 PM

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.

Comment
Add comment · Show 4 · 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 Wolfram · Jun 27, 2012 at 03:59 PM 0
Share

I believe this actually answers @sebas' question. See my answer for a more detailed explanation/analysis.

avatar image huulong · Sep 08, 2015 at 05:23 PM 0
Share

It may be fixed in Unity 5.1.3, or maybe my case has some subtle differences.

I tried to make a $$anonymous$$onoBehaviour B with OnEnable be run after another $$anonymous$$onoBehaviour A with no OnEnable, and it worked. I wanted A.Awake() to quickly deactivate the game object of B so that B.OnEnable() was not called at the beginning of the game (not critical, but it would cause unneeded initialization of B just before being deactivated anyway). Script A managed to deactivate game object B before B.OnEnable() was called.

avatar image Fattie · Mar 07, 2016 at 02:04 PM 0
Share

This IS NOT FIXED even in the latest Unity ($$anonymous$$arch 2016).

Adding OnEnable in your low-order script DOES NOT SOLVE the problem unfortunately.

avatar image Oliver-Bogdan · Apr 28, 2016 at 04:19 PM 1
Share

I can confirm that this DOESN'T WOR$$anonymous$$ in 5.3.4f1. What worked for me was to change the execution order for the two scripts.

Edit > Project Settings > Script Execution Order

avatar image
3

Answer by Bunny83 · Feb 17, 2012 at 04:19 PM

OnEnable and Awake are called when the objects / script instance is created. They are propably called from the internal constructor. They are even called before Instantiate returns. There is no way to influence when awake / OnEnabled is called on scene objects. The execution order you can set in Unity only influences the Unity generated events like Start, Update, LateUpdate ...

Avoid code in Awake which relies on other object. Start is made for this purpose. Start is called after all scene objects are created and all Awake function has been called. In general you should use Start to initialize object dependencies.

Comment
Add comment · Show 7 · 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 sebas77 · Feb 17, 2012 at 06:50 PM 0
Share

Thanks for the answer. Are you telling me that the script execution order controls only the Start order and not the Awake order?! However I do not think they are called inside the constructor, but I do think they are called right after.

avatar image Bunny83 · Feb 19, 2012 at 06:50 AM 0
Share

Yes, you can't control when Awake is called since it's actually the direct replacement for the constructor. Awake might be called from the constructor, but we don't know how Unity handle those things behind the scenes. That's why i said the "internal constructor". Don't forget that almost every object in Unity has also a c++ native code class-part behind the scenes. Unity isn't written in managed code, only the scripting environment uses $$anonymous$$ono. When you "add" a component a lot things happens which you don't see and you can't influence.

avatar image Noise crime · Jun 27, 2012 at 02:06 PM 1
Share

According to the docs there are several aspects that are incorrect from Bunny83's reply. Firstly script execution order does deter$$anonymous$$e when Awake is called (http://docs.unity3d.com/Documentation/Components/class-ScriptExecution.html). Secondly 'Awake is called after all objects are initialized so you can safely speak to other objects or query them' (http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$onoBehaviour.Awake.html), so its perfectly safe to use code in Awake that replies on other objects.

Further more you need to take care if using Start to initialise object dependencies since if the object is enabled, its OnEnable will be called first, and if you try to use those dependencies they will not be set up yet.

As to your problem check my reply below and see if its to do with a known bug when using OnEnable in other scripts but not in the one you are trying to force the script execution order for.

avatar image Wolfram · Jun 27, 2012 at 04:05 PM 0
Share

@Noisecrime: I believe with "Avoid code in Awake which relies on other object" @Bunny83 is talking about situations where you are referring to other objects that also initialize themselves in Awake(). For example, for a given scene hierarchy where the same script type is attached to all objects, the children (or some children) of an object might already have their Awake() being executed, while the parent object has not. Or vice versa - it might be non-deter$$anonymous$$istic. In addition, if you are instantiating stuff in Awake(), you cannot relie upon in other Awake() functions that these objects have been created already. So you might want to do your instantiations in Awake(), but any Find()/FindObjectByType() etc. in Start.

avatar image Bunny83 · Jun 27, 2012 at 06:29 PM 2
Share

The whole execution order thing doesn't work at all. It does work when a level is loaded, but try instantiating a prefab at runtime... The only thing that follows the execution order is Update / LateUpdate ... Start / Awake / OnEnable ... are not in the specified correct order.

You also have to distinguish between serialized objects which are stored in a scene and runtime generated instances. Awake is called when the object is "loaded". Again, when you call AddComponent to add a certain script, awake will be called before the AddComponent function returns. Same thing for Instantiate(). Awake and OnEnabled will be called before Instantiate returns. If you have two scripts attached that have been arranged in a certain execution order, they won't follow it.

btw. I've done a lot analysis on this issue in the past. The script execution order is a quite new feature which was buggy since it has been implemented. Afaik they fixed it partially, but in the end it still doesn't work.

It actually doesn't make much sense to overanalyse it. Fact is: you can't rely on it, so don't rely on it!

It is true that when a scene is loaded, all serialized objects are created before Awake is called. The objects are actually created two times (just put a debug log into the constructor). First time in the object creation order (the order they have been created / saved / ...) and again when they get deserialized. The deserialization for scene objects follows the execution order. Then all Awake functions are called then Start. They follow the execution order, but only when they are serialized objects in a scene.

You shouldn't take the docs for granted. There are many cases where the docs had wrong examples or misinformation. It often describes how it should work, not how it actually works.

Show more comments
avatar image
0

Answer by Ashkan_gc · Feb 17, 2012 at 02:31 PM

The manual is not that clear about it. It mentioned OnEnable after Awake in list order but it only said clearly that all Awakes will be called before any Start. again in summary it only shows Start and Awake and not OnEnabled. but for Awake says it will be called After Instantiation and for OnEnabled it says after object becomes enable so theoratically Awake should be sooner than OnEnable.

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 Immanuel-Scholz · Nov 07, 2013 at 01:33 PM

I just submitted another strange bug, where the scripting order gets violated. If you have the following setup in your hierarchy (where "Prefab" is any prefab instance):

 GameObject
    +- Prefab
       +- GameObject
          +- Prefab
          +- ObjectWithUnmportantComponent
 ObjectWithImportantComponent

Then the component of "ObjectWithUnmportantComponent" gets executed first, even if it has a script order number higher than a component in "ObjectWithImportantComponent".

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 davekalina · Dec 03, 2013 at 08:07 PM 0
Share

Did you ever get resolution on this bug? We're seeing something similar that is completely messing up our scripts (unreliable order of execution will do that to you!)

avatar image Immanuel-Scholz · Dec 03, 2013 at 10:37 PM 0
Share

Unfortunately not.

We are doing our own execution callback system (for various other reasons as well. This one in case here is actually not the biggest problem. $$anonymous$$uch worse - for example - is an totally undefined and jagged destruction order)

  • 1
  • 2
  • ›

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

22 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

Related Questions

Execution Order of Scripts - Awake and OnEnable 1 Answer

Should OnEnabled() be changed to be called after Start()? 1 Answer

If a script is attached to more than one gameObject, will Start() & Awake() run more than once? 2 Answers

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

Am I using OnEnable() correctly here? 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