Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
19
Question by mlepage · Apr 08, 2015 at 12:47 PM · scenestartenabledawakedisabled

Something like Awake that runs even if disabled?

The documentation for Start says:

Like the Awake function, Start is called exactly once in the lifetime of the script. However, Awake is called when the script object is initialised, regardless of whether or not the script is enabled. Start may not be called on the same frame as Awake if the script is not enabled at initialisation time. http://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html

It always seemed to me like Awake would be called regardless of whether an object were enabled or not, whereas Start would be called only when the object became active. And that this would apply to app startup. But that does not appear to be the case.

http://forum.unity3d.com/threads/unityevent-disabled-objects-awake-failure.267241/

My question is whether there is anything like Awake that is called even on disabled objects when the app is started. Because that would be terribly handy. (Or am I misunderstanding Awake, maybe it does somehow run on disabled objects at startup?)

So I think I do understand the difference between Awake and Start. If you Instantiate an object then disable it, Awake will run but Start will not. So you should initialize the object itself in Awake and its connections in Start.

What I'm asking is why can't there be another callback, like Init, which runs only at app startup, for all disabled objects in the scene, if it exists. Unity could make a list of which ones to call when it builds the scene, so it doesn't have to traverse the scene hierarchy at startup. (This is basically how static initialization functions are compiled in some languages.)

At the very least I think the docs should be clearer that Awake is not called at startup if the object is not enabled, because it really seems like it would be, as the docs currently describe.

Comment
Add comment · Show 4
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 Bonfire-Boy · Apr 09, 2015 at 05:00 PM 0
Share

It might help people to try of think of ways to achieve what you're after, if you explain what use you want to put it to.

avatar image puppeteer · Jul 31, 2015 at 06:53 PM 0
Share

Seconded for the question. This is very important if you want for example to check if the mute button should be on or off, and the mute button is part of an options menu.

Now the problem is that you don't want that UI menu to clutter the whole game area while editing, but you can't disable it because it won't make that check on scene startup.

avatar image Bonfire-Boy · Aug 01, 2015 at 07:45 PM 0
Share

I agree that the documentation isn't too clear, but the way things work seems pretty good to me. If I put an object in my scene in the editor but deactivate it, I want it to be like it's not even there... until I activate it.

But I think there are ways of achieving what you're after. For example, you can have another object in the scene, with a reference to the deactivated object(s), which calls their initialisation function(s) in it's Awake/Start. That would probably be my approach to puppeteer's situation - I'd initialise bits of my UI from a UI$$anonymous$$anager of some sort, so that they could be initialised regardless of whether they're active.

Another approach would be to make the object active but have its components disabled, so that their Awakes get called on scene start up but that's all, until they're enabled.

But I should say that neither of the above is something I've ever actually found myself needing to do, so it may be that I'm missing something.

avatar image tormentoarmagedoom · Nov 05, 2018 at 06:50 PM 0
Share

Objects are active or inactive. The components like a script, are enabled or disabled

11 Replies

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

Answer by g.g.lang · Dec 10, 2015 at 11:34 PM

The constructors of scripts will run on disabled GameObjects.

For example, the following script will output "Constructor" into the log if it is on a disabled GameObject:

 public class TestDisabled {
 
 public TestDisabled() {
      Debug.Log("Constructor");
 }
 
 void Awake()
 {
     Debug.Log("Awake");
 }
 
 void Start()
 {
     Debug.Log("Start");
 }
  
 void OnLevelWasLoaded(int level)
 {
     Debug.Log("OnLevelWasLoaded");
 }
 
 }





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 mlepage · Dec 11, 2015 at 12:00 AM 0
Share

Ah, that could be handy, thanks!

avatar image puppeteer · Dec 12, 2015 at 07:29 PM 1
Share

The problem with this is that it will run the content of the function erratically during Editor time too.

avatar image Ratboy601 · Feb 03, 2016 at 11:51 AM 0
Share

@puppeteer Yes, that's true! I tried this, but I was quickly able to solve that problem by giving my constructor function a boolean parameter, and wrapping all functions within it in an if statement. So it will only run in the editor (in full) if that boolean is set to true externally. Voila, no more annoying console errors!

avatar image Bip901 · Oct 03, 2020 at 01:59 PM 0
Share

You should NEVER use the constructor of a $$anonymous$$onoBehaviour. Unity might call the constructor multiple times. It's also not executed on the main thread.

avatar image
4

Answer by hubatish · Apr 09, 2015 at 04:27 AM

That is pretty lame documentation. On the Monobehavior description they say this:

Note: The checkbox for disabling a MonoBehavior (on the editor) will only prevent Start(), Awake(), Update(), FixedUpdate(), and OnGUI() from executing. If none of these functions are present, the checkbox is not displayed. http://docs.unity3d.com/ScriptReference/MonoBehaviour.html

I just tried it out with Awake, Start, and OnLevelWasLoaded

     protected void Awake()
     {
         Debug.Log("Awake");
     }
 
     protected void Start()
     {
         Debug.Log("Start");
     }
 
     protected void OnLevelWasLoaded(int level)
     {
         Debug.Log("OnLevelWasLoaded");
     }

With an enabled object I got both Start and Awake, with a disabled object, neither, and neither called OnLevelWasLoaded.

In answer to the Init question: if you really wanted to, I'm sure you could call a custom Init function using OnLevelWasLoaded and an object with the DontDestroyOnLoad attribute. If you're more specifically interested in an OnApplicationStart event you could have a scene specifically for initialization scripts.

I believe OnLevelWasLoaded is called in any object that is not created in the scene but was not destroyed in the previous scene. Official docs: http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnLevelWasLoaded.html

However, it's probably easier to just disable the object in the Awake event.

Comment
Add comment · Show 1 · 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 hubatish · Apr 09, 2015 at 01:40 PM 0
Share

sorry for the double post - I'm not sure why mods have to approve answers on this site.

avatar image
3

Answer by brinca · Aug 18, 2018 at 04:44 AM

Having a Create() method that gets called even if the object is inactive would be awesome, but alas, not (yet) supported, so perhaps the next best thing is to make your own... ;)

The approach I use uses an interface IInitable that defines a single Init() method:

 public interface IInitable {
    void Init();
 }

On the scene manager (or any other script for that matter), I gather all the instances that implement IInitable, and call Init() on them:

 var scripts = gameObject.GetComponentsInChildren<IInitable>(true);
 
 foreach (var script in scripts)
     script.Init();

Yes this is slow (you should use this only when setting up the scene), and yes it'll not work when instantiating new objects (but then you can call Init() manually), but it gets the job done.

Final tip, if you don't have all your game objects under a single root (what I call the scene manager), you'll have to iterate each root object of each scene when looking for IInitable instances:

 var scripts = new List<IInitable>();
 var scene = SceneManager.GetActiveScene();
 
 var rootObjects = scene.GetRootGameObjects();
 
 foreach (var go in rootObjects)
     scripts.AddRange(go.GetComponentsInChildren<IInitable>(true));

 foreach (var script in scripts)
     script.Init();
Comment
Add comment · Show 14 · 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 Bonfire-Boy · Aug 18, 2018 at 02:41 PM 0
Share

Another option, is to give the scenemanager the responsibility of deciding which objects can have this done. You could for example give it a public array of gameobjects which you populate with those objects. This would speed things up (no need to find them) and also give you a bit more flexibility (you'd still have the option of properly turning the objects on and off, by removing/adding them to the array)

avatar image brinca Bonfire-Boy · Aug 19, 2018 at 08:44 AM 0
Share

Linking the instances to the scene manager, either through references in the Editor or through code is the optimal way of course, but that isn't the point of the OP's original question... in cases where you either can't or don't want to link explicitly (e.g. if you want to decouple your scripts from the scene manager), then my suggestion provides a nice way to implement a callback that is always run, even if the game object is disabled.

avatar image Bonfire-Boy brinca · Aug 19, 2018 at 09:49 AM 0
Share

This way of doing things isn't for me, as explained above. But I recognise that some people might want to do it. So my comment to your answer wasn't intended to criticise it, just pointing out "another option", as I said.

But I'm not sure what you mean by "decouple from the scene manager". How does my tweak make anything more dependent on the scene manager than yours? All it does it change how the scenemanager gets to know about the IInitables

Show more comments
avatar image the_mr_matt · Nov 05, 2018 at 06:34 PM 0
Share

How would I go about creating a priority system for this? Before I relied on the script execution order to ensure my scripts initialized in a specific order but calling them manually from one script breaks that. I can't put a field into the IInitiable interface for priority and I don't want to make an abstract class because I'm already inheriting from other abstract class and it would just become a mess.

avatar image brinca the_mr_matt · Nov 05, 2018 at 06:48 PM 0
Share

When you say you can't is it because the requirements won't allow it, or is it simply because interfaces don't support fields?

If the latter, simply use a property int Priority { get; set; }, and then sort the scripts array before calling Init().

If the former, then one way to get around that would be to use interfaces to mark the script's priority (IPriorityHigh, IPriorityNormal, IPriorityLow, etc), then check for those when finding the instances if (script is IPriorityHigh) ...and store them into different arrays, then call Init() on each array according to it's priority.

avatar image the_mr_matt the_mr_matt · Nov 05, 2018 at 06:54 PM 0
Share

Got it to work using a property. I can just return a constant integer in the property and then in before initializing the scripts I sort the list by the priority property using linq. Gonna be awfully slow but it works...

avatar image brinca the_mr_matt · Nov 05, 2018 at 06:56 PM 0
Share

No problem in being slow if it's not performance critical... ;)

Show more comments
avatar image moment_um · Jun 04, 2019 at 06:17 PM 0
Share

I might be mistaken, but calling GetComponentsInChildren does not work on inactive gameobjects. So we run back into the same problem.

avatar image Bunny83 moment_um · Jun 04, 2019 at 06:31 PM 0
Share

GetComponent(s) should always work, no matter if the object is active / deactivated or if the component is enabled or not. GetComponentsInChildren has an optional parameter to specify if deactivated gameobjects should be traversed or not. As you can see in the code he provided he passed "true".

avatar image
1

Answer by MikkaW · Jul 25, 2016 at 04:13 PM

Another workaround:

Since the constructor solution kept throwing Errors i found another way to do it (in my case it worked):

I encapsulated my GameObject with another empty GameObject which has a script attached to it doing the initialization stuff. The top GameObject is enabled (and therefore executes Start() and Awake()) while the child is disabled and gets enabled when needed.

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 hbalint1 · Apr 08, 2015 at 04:58 PM

https://unity3d.com/learn/tutorials/modules/beginner/scripting/awake-and-start

I think this describes it very well :)

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 mlepage · Apr 08, 2015 at 08:36 PM 2
Share

Yes we've all seen that video but it does not address my question. I asked if there is something like Awake which will be called at startup even for an object which is not enabled. If you watch that video you'll see it doesn't answer my question.

avatar image hbalint1 · Apr 08, 2015 at 09:06 PM 0
Share

"Awake called first, even if the script component is not enabled." So if you have your GameObject in the scene with you own script component which is disabled, it's Awake method will be still executed. So as you asked, Awake will be executed on disabled objects at startup.

avatar image mlepage · Apr 08, 2015 at 09:55 PM 1
Share

Not quite. Awake will be called for disabled components on enabled objects; it will not be called for disabled objects. It's important to consider this distinction. I am asking specifically in my question if there is anything like Awake that will be called for disabled objects.

avatar image hbalint1 · Apr 08, 2015 at 10:12 PM 0
Share

Oh sorry. then I misunderstood your question. my mistake. I found you this. so Awake is really not good for you. http://answers.unity3d.com/questions/372752/does-finction-start-or-awake-run-when-the-object-o.html

  • 1
  • 2
  • 3
  • ›

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

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

Related Questions

does finction start or awake run when the object or script is enabled mid game 3 Answers

How to make Awake and Start get called in order with additive scenes? 1 Answer

What Happens in Scene Load 1 Answer

How would I load a Canvas from another scene? 3 Answers

ExecuteInEditMode Component construct "twice" and "reset" custom classes 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