Confused by Awake() documentation on enabled / disabled script

Hello,

On the Unity documentation of MonoBehaviour.Awake(), I read the explanation starts with the following mention : “Awake is called when an enabled script instance is being loaded.”

But my understanding is that Awake() is called even if the script is disabled.
So isn’t the mention kind of wrong?
Shouldn’t it be something like “Awake is called when a script instance is being loaded.”?

Thanks in advance…

Well to answer your question about when its called, did you try it?

EDIT: See posts below for more nuance.

using UnityEngine;

// @kurtdekker
// - make a completely-blank scene
// - make two GameObjects, name them ACTIVE and INACTIVE
// - add this script to each GameObject
// - set one GameObject to Active and the other to Inactive
// - run

public class ReportNameOnAwake : MonoBehaviour
{
    void Awake()
    {
        Debug.Log(GetType() + ".Awake(): my name is " + name);
    }
}

Are you asking if I tried if a Awake() is called even when the script component is disabled?
Yes I tried, or at least I think I tried…

I write the following script and make it a component of an active gameObject.
But I uncheck the script component to make it disabled, just like the attached picture.
And when I play, I see “awake” is logged in console.
So I think the Awake() is being called even when it’s disabled.

using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
void Awake()
{
Debug.Log(“awake”);
}
}

This is by design. If you read a bit further in the documentation you will find “Awake is called even if the script is a disabled component of an active GameObject.”

Thanks for that callout… I think I see the confusion.

What you are seeing is the cascade of Unity initialization in a running scene.

YES you unchecked enabled.

But when the scene is loaded and .AddComponent() is called on your behalf, new script instances are enabled and there is no way to change this… UNLESS the GameObject is disabled.

Now… long after AddComponent() has happened and Awake() has been called… Unity deserializes the state of that script, all the public serializables, such as .enabled

Now it looks disabled… and yet Awake fired.

I retract my troll observation above. :slight_smile:

More broadly…

Serialized / public fields in Unity are initialized as a cascade of possible values, each subsequent value (if present) overwriting the previous value:

  • what the class constructor makes (either default(T) or else field initializers, eg “what’s in your code”)

  • what may be saved with the prefab

  • what may be saved with the prefab override(s)/variant(s)

  • what may be saved in the scene and not applied to the prefab

  • what may be changed in the scene and not yet saved to disk

  • what may be changed in OnEnable(), Awake(), Start(), or even later

Make sure you only initialize things at ONE of the above levels, or if necessary, at levels that you specifically understand in your use case. Otherwise errors will seem very mysterious.

Here’s the official discussion: https://blog.unity.com/technology/serialization-in-unity

If you must initialize fields, then do so in the void Reset() method, which ONLY runs in the UnityEditor.

Field initializers versus using Reset() function and Unity serialization:

https://discussions.unity.com/t/829681/2

https://discussions.unity.com/t/846251/8

To avoid complexity in your prefabs / scenes, I recommend NEVER using the FormerlySerializedAsAttribute

Now I get it.
It’s very clear now.
Thank you so much!