OnEnable Is Called Twice For MonoBehaviours With The [ExecuteAlways] Attribute

When entering playmode, OnEnable will be called twice for MonoBehaviours with the [ExecuteAlways] attribute. Aside from performance problems of double initialization, the first OnEnable also does not follow the execution order of the script.

In my case, I have a UI Toolkit UIDocument, where I want to add VisualElements to the rootVisualElement.
In EditMode, this works just fine because OnEnable is called after the UIDocument.
In PlayMode, this throws errors because OnEnable is called twice. Once some time before the UI Document and once when it should be called.

Expected behavior is that a script with execution order of -50 should execute after a script with execution order of -100.

[DefaultExecutionOrder(-50)]
public class ExampleCanvas : MonoBehaviour
{
    //Assigned in the inspector
    public UIDocument document;//Execution order of -100

    private void OnEnable()
    {
        Debug.Log("Enable");//This will log "Enable" twice

        document.rootVisualElement.Add(new VisualElement());

        //First OnEnable:
        //[Error] UIDocument has yet to be initialized, so rootVisualElement is still null

        //Second OnEnable:
        //[No Error] UIDocument has been initialized, so rootVisualElement is no longer null
    }
}

Hi @Nexer8 ,

Please note that the [DefaultExecutionOrder] attribute is not officially supported and shouldn’t be used. We have the Script Execution Order settings for that purpose.

How does that work with Assets? In my case, I need the scripts to work in a certain order and if that order is not preserved for the users, or if the users can change it, then that would be a bad thing.

The execution order of a script is saved in its .meta file. So it’s preserved properly.

1 Like

Good. Do you know if derived classes also have this execution order or if I have to manually set it for all of them?

The fact that you can set the order for base and derived class separately tells me it doesn’t affect the derived classes, and then there is this:

https://answers.unity.com/questions/664630/does-script-execution-order-effects-extend-to-desc.html