0
\$\begingroup\$

I have this:

[InitializeOnLoad]
public class MyClass
{
    static MyClass()
    {
        EditorApplication.playModeStateChanged += x => { PlaymodeStateChanged(); };
    }

    private static void PlaymodeStateChanged()
    {
        Debug.Log("Play mode changed");
    }
}

and another class with a Debug.Log("Start()"); in the Start method. When I hit play I see on the log output:
Start()
Play mode changed

Shouldn't playModeStateChanged get called before Start is called on all objects? Any way to go around this? I need this so I can initialize an object before other objects that need to reference this one run Start.

Thanks in advance!

\$\endgroup\$
1
\$\begingroup\$

My best guess based on the docs:

EditorApplication.playModeStateChanged

Add an event handler to this event to receive a notification that the play mode state has changed

Note the use of past tense - this event promises to notify you only after the state has changed. It's not a playModeStateWillChange event.

But clearly your static constructor is getting called earlier, thanks to the [InitializeOnLoad] attribute:

Note that static constructors with this attribute are called when Unity starts and when Run is pressed. In this second case the Unity runtime is intialised and this is treated as a Load.

So it looks like, rather than registering to handle the event after the editor finishes starting playmode (which apparently includes calling Start() for all MonoBehaviours in the open scenes), you could act immediately in the static constructor.

Since this constructor also fires when the editor loads, you might need to check:

EditorApplication.isPlayingOrWillChangePlaymode

Is editor either currently in play mode, or about to switch to it? (Read Only)

This will return true when editor will switch to play mode after finishing some tasks (e.g. after scripts will be recompiled).

to verify whether this initialization is due to the editor loading or a play mode switch.

Give that a shot, and let us know if that helps you get your needed actions in before Start() happens.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply DMGregory. I tried your solution and I'm getting closer to solving this. I'm using PlayModeStateChanged to spawn a gameobject and it gives me this error: Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?) so I guess I cant spawn stuff from there. Do you happen to know if there is a way to know if Awake is running/has ran? \$\endgroup\$ – ItsaMeTuni Apr 7 '18 at 21:25
  • 1
    \$\begingroup\$ I just found out about UnityEditor.Callbacks.PostProcessSceneAttribute. I'm using it to instantiate my object. I am aware that it wont work on a build, but for me this isn't a problem since I only need this in the editor. You put me in the right direction, thank you! \$\endgroup\$ – ItsaMeTuni Apr 7 '18 at 21:57
  • \$\begingroup\$ @ItsaMeTuni That sounds like a better solution than what I proposed above. I recommend writing that up as an answer and (after the short waiting period) marking it as the accepted answer. \$\endgroup\$ – DMGregory Apr 7 '18 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.