Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Awake called before [RuntimeInitializeOnLoadMethod] -> LoadScene in Editor

Discussion in 'Editor & General Support' started by Flavelius, Jan 2, 2020.

  1. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    927
    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.
     
    keni4 likes this.
  2. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    927
    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 https://docs.unity3d.com/ScriptReference/SceneManagement.EditorSceneManager-playModeStartScene.html makes it behave normally/as expected, as a bad workaround.
    I could consider this a valid workaround if it was exposed somewhere usable.
     
    Last edited: Jan 3, 2020
  3. Baydogan

    Baydogan

    Joined:
    Mar 22, 2018
    Posts:
    54
  4. RDeluxe

    RDeluxe

    Joined:
    Sep 29, 2013
    Posts:
    116
    Yep, same issue here !
     
  5. Baydogan

    Baydogan

    Joined:
    Mar 22, 2018
    Posts:
    54
    I found the solution to this issue.

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

    Code (CSharp):
    1. [InitializeOnLoad]
    2. public class EditorInit
    3. {
    4.     static EditorInit() => EditorSceneManager.playModeStartScene = AssetDatabase.LoadAssetAtPath<SceneAsset>(EditorBuildSettings.scenes[0].path);
    5. }
     
    andreyefimov2010 likes this.
  6. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    927
    This is what i wrote in the second post above, it's not really a solution, but a workaround
     
  7. Baydogan

    Baydogan

    Joined:
    Mar 22, 2018
    Posts:
    54
    Sorry, I replied to the wrong thread.

    But I think this is not an ugly workaround.
     
  8. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    927
    I attached a small editor script that exposes the startup scene in the project settings. (2018.3+)
     

    Attached Files:

  9. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    927
    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.
     
  10. KingAustin

    KingAustin

    Joined:
    Jan 12, 2016
    Posts:
    20
    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
    https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html
    How the main attribute works
    https://docs.unity3d.com/ScriptReference/RuntimeInitializeOnLoadMethodAttribute.html
    constructor
    https://docs.unity3d.com/ScriptReference/RuntimeInitializeOnLoadMethodAttribute-ctor.html
    the data for it
    https://docs.unity3d.com/ScriptReference/RuntimeInitializeLoadType.html

    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,
     
    Xriuk likes this.
  11. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    927
    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!
     
  12. Kleptine

    Kleptine

    Joined:
    Dec 23, 2013
    Posts:
    256
  13. Mjbgtaad56

    Mjbgtaad56

    Joined:
    Aug 1, 2015
    Posts:
    4
    I'm having this issue as well.

    I have a function with the following attribute:
    Code (CSharp):
    1. [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.
     
  14. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    324
    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.
     
  15. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    927
    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)
     
  16. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    324
    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.