Awake called before [RuntimeInitializeOnLoadMethod] -> LoadScene in Editor

How can i work around this behaviour that smells like a bug that calls Awake in open scenes before a RuntimeInitializeOnLoadMethod method loads the actual first scene when hitting play in the editor?
What happens:
MyBehaviour.Awake = SceneManager.sceneLoaded += HandleSceneLoaded basically.
1: [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] → SceneManager.LoadScene(“MyStartupScene”);
DontDestroyOnLoad(Instantiate(Obj with MyBehaviour));
2. MyBehaviour.HandleSceneLoaded() invoked for every scene that was open in the editor;
3. (Instantiated Obj)MyBehaviour.HandleSceneLoaded() invoked;

When i unload every scene and load a placeholder before entering playmode this doesn’t happen, but i don’t really want to do that everytime and restore the setup again afterwards.

1 Like

SceneManager.LoadScene(), then Instantiating a GameObject in RuntimeInitializeOnLoadMethod puts it into the first scene that’s open in the editor. I think that’s a bug, as scenes from the editor shouldn’t leak into playmode.
Is that leakage intended?

Edit: Setting Unity - Scripting API: SceneManagement.EditorSceneManager.playModeStartScene makes it behave normally/as expected, as a bad workaround.
I could consider this a valid workaround if it was exposed somewhere usable.

+1

Yep, same issue here !

I found the solution to this issue.

Put this editor script into an editor folder.
This way you can set your initial scene programmatically.

[InitializeOnLoad]
public class EditorInit
{
    static EditorInit() => EditorSceneManager.playModeStartScene = AssetDatabase.LoadAssetAtPath<SceneAsset>(EditorBuildSettings.scenes[0].path);
}
1 Like

This is what i wrote in the second post above, it’s not really a solution, but a workaround

Sorry, I replied to the wrong thread.

But I think this is not an ugly workaround.

I attached a small editor script that exposes the startup scene in the project settings. (2018.3+)

6070437–658083–EditorSceneSettingsExtension.unitypackage (837 Bytes)

Unfortunately this setting doesn’t seem to be saved and there’s no way to mark static classes as dirty, so this is not a good workaround after all.
Please, unity, expose this setting properly.

I found this thread when i was doing research into the very long named attribute “RuntimeInitialiseOnloadMethod”
The thread is not as dead as i first thought but i would still like to learn more and see if i can give help, though not sure how good it would be to someone who has done research for 6 months.

the few important links are as follows
how awake works

How the main attribute works

constructor

the data for it

Based on what i can see, it says the basic attribute without any extra data should load after awake, this is probably the data “after scene load”. i have no idea where before scene load should be called.

I also have no idea how to experience the exact idea you are saying.
Im not sure how new you are with unity as well but the scene you have currently loaded is always activated when you press play i dont know how this reactors to having multiple editor scenes open at once as i never had to do that. it sounds like all your active scenes were played at once and loaded at once.

the attribute does not need to be attached to a monobehaviour to work either and will fire off for every scene that is activated and for newly loaded scenes too i think. im not sure how that did not end up into an infinite loop either. i have not tested this multiple fire offs though but i have used it outside monobehaviours.

tell me if i get anything wrong or if you already know this,

1 Like

Hey, thanks for the nice reply. Unfortunately i’m already very familiar with the way unity works and the only painpoint here is the one that you too mentioned as being not sure where it should be called (beforesceneload). As this is not doing what’s expected i’ve already went on and used a special editor script to work around that case as it’s mainly an editor oddity in my case → i’m only using it to ensure a special scene is always loaded first. At runtime that’s not a problem, so that’s okay (there are other far more serious bugs).
But thanks for trying to help!

Some updated information. Some of the non-default load types do run before awake:
https://uninomicon.com/runtimeinitializeonload

4 Likes

I’m having this issue as well.

I have a function with the following attribute:

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]

But it runs after another script calls Awake() for some reason.

This is technically not an issue, but I would prefer not to have error messages complaining about objects not existing because the initial scene has not been loaded yet.

It sounds to me like the original poster Flavelius was hoping that BeforeSceneLoad would allow them to load a preferred scene, without fully loading the open scene in the editor, so that they could actually load a different scene every time. However, I don’t think that’s how it works, or was designed, or will probably ever work. BeforeSceneLoad happens before the Awake methods on MonoBehaviours in the scene, but whatever scene is open in the editor is still going to be fully loaded and all of the MonoBehaviours will still Awake and Start, even if you requested that a new scene be loaded ASAP. That was their problem, if I understand it correctly. BeforeSceneLoad requests a new scene to be loaded, then the MonoBehaviours in the scene they happened to have open in the editor would still Awake, running undesired code, then the desired scene would be loaded, but those undesirable Awake calls already occured before their preferred scene gets loaded. It’s not really a bug, just the way it is, and I would presume that it’s unlikely to change.

If you are having a different issue where Awake methods are actually occuring before BeforeSceneLoad, my first guess would be that it’s because those MonoBehaviours are editor scripts, not runtime-only MonoBehaviours. However, you will probably need to provide some example code that demonstrates the behavior to really understand your particular issue.

You correctly described my intention.
I don’t see how you would still classify this as not-a-bug, as it’s loading the scene, then invoking the callback while it clearly says "before"sceneload.
If any awake is called before it, it cannot be ‘before’ scene load, because awake is only called after an object has finished initializing, in which case the scene it belongs to is also already loaded, as gameobjects cannot have their monobehaviour callbacks invoked without being inside a scene.
Otherwise it should be called before(Scene?)Awake.

but whatever scene is open in the editor is still going to be fully loaded and all of the MonoBehaviours will still Awake and Start
what does the ‘still’ refer to if not a misbehaviour or misnomer of the attribute?
Unity typically reloads the scene and the scripting domain on play (ignoring fast-enter-playmode that is not used here)

I agree that it’s not the best name. The term scene “loading” is definitely being used in inconsistent ways by different systems in the engine. I just have doubt that Unity is likely to change the behavior significantly.

I’ve been looking at what things can be done in the RuntimeInitializeOnLoadMethod callbacks recently and it appears to me that the scene you have open in the Editor is considered loaded and active when you press Play and initialize the runtime. Just try printing SceneManager.GetActiveScene().name during the RuntimeInitializeLoadType.SubsystemRegistration, RuntimeInitializeLoadType.AfterAssembliesLoaded, or RuntimeInitializeLoadType.BeforeSplashScreen callbacks. It seems that the open scene is already loaded when the runtime initializes. If you try to change the scene during the runtime initialization, then the initialization will finish all of its steps first before the scene you requested to load actually gets loaded.

One thing that I’ve found that might be helpful to you is that you can manipulate GameObjects in the scene you have open in the Editor before their Awake() or Start() functions are called. You can do this in the RuntimeInitializeLoadType.BeforeSceneLoad callback before you try loading the scene you actually want to start with. For example, you could grab all the GameObjects and set them inactive. Then Awake() or Start() won’t be called as the runtime initialization steps finish, after which your requested scene will load.

1 Like

Or, you could just not require any special scene to be loaded first in order for your game to start.

While this might be a useful consideration for some games, many still do require a certain scene to run first for systems initialization (that may require user feedback), menus, intro, additive scene loading, starting a level-sequence etc. . It’s not easy to rework that into a setup that is cleanly initializable from every scene without introducing unnecessary complexity while not even gaining any real benefits, because the built player also requires a single scene to be the initial one which means it works perfectly fine at runtime by default. It’s just the editor that’s misbehaving here.
Deactivating all sceneobjects sounds like a simple and effective workaround though!
Until now i was using EditorApplication.playmodeStartScene, but this has the issue that the assignment seems to stick around for as long as the editor is open, so it requires using some clearing mechanism first to also be able to start single scenes temporarily, after it was assigned just once.

The benefit is that you can hit play in any scene and instantly be testing your game in a matter of milliseconds. Do you truly require a lot of input from the user before you can playtest a demo scene? Can’t anything you would require of the user simply be replaced with test values, which you can just tweak in the editor to whatever you like before pressing play, unless you happen to be in that startup scene doing the typical boot sequence?