Search Unity

Duplicate scenes in editor with loadadditive and check if already loaded

Discussion in 'Editor & General Support' started by Flavelius, Jan 3, 2019.

  1. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    Hi,
    I'm trying to have a play-from-every-scene setup that checks whether the manager scene is already loaded and if not loads it to begin play from the current scene.
    But strangely, the manager scene is loaded twice with these simple lines:

    Code (CSharp):
    1. if (!SceneManager.GetSceneByName("Main").isLoaded)
    2. {
    3.     SceneManager.LoadScene("Main", LoadSceneMode.Additive);
    4. }
    It is already open in the editor before i hit play, but if it is loaded this check should fail, but it seems it doesn't, so the scene is opened twice.
    Is this a bug/can i prevent it without remembering to manually close the manager scene first?

    Edit: the check and loading is done in Awake()
     
    Mikael-H likes this.
  2. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    Ok, looks like there's a bug. If i iterate the scenes with GetSceneAt and scenesCount, i can see the 'Main' scene, but isLoaded is false (the documentation says, GetScenesAt should return loaded scenes). Then after loading it, i have two of them open *and* loaded.
     
  3. I'm confused. You mention GetSceneByName then GetSceneAt, which one you have problem with?

    I have tested the GetSceneByName with the scene opened in the editor, it works like a charm in 2018.3 latest. The scene gets unloaded upon play and by the time of the Awake it says it's not loaded (check on the isLoaded property).
     
  4. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    Yes, GetSceneByName should not even return the scene (the documentation says loaded scenes). And because it is returned and marked as not loaded i load it (and that way it gets loaded twice, which it also shouldn't). I mentioned GetSceneAt in the context of trying to find the cause and iterating all open scenes alternatively instead of using GetSceneByName.
     
  5. Oh I see what you say. It's probably a documentation bug (or changed behavior which is not yet reflected in the documentation).
    Duplication happens if you put it in a script which runs on multiple objects on awake. Because scene loading happens at the end of the frame, so all of the awakes will schedule a load for the scene additionally.

    Edit: I mean can happen.
     
  6. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    I checked again (even with 'find references in scene') but i only have it on exactly one object (basically it's only in one scene too, the one that's not loaded in dynamically).

    Edit: it works if i rightclick-> unload scene on the specific scene before play (so it's still in the hierarchy, but not loaded); that way it doesn't get loaded twice, but as i wrote i don't want and shouldn't need to manually do this everytime (as all non-active scenes should be auto-removed on play anyway).
     
    Last edited: Jan 3, 2019
  7. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    It also works as expected (not as a fix) if i move it from Awake() to Start() and yield a frame before checking and loading.

    Edit: Interestingly, i just noticed that the current scene setup is actually kept for in-editor play (non-active scenes are not removed). So that's one of the issues (is there a setting to control this?), and the other that during Awake the checked scene is marked as not loaded and can actually be loaded twice this way (with no way of controlling this duplication)
     
    Last edited: Jan 4, 2019
  8. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    Submitted a bug report that got the number 1115217
     
  9. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    I received the reply that this is intended. That means there's no way to check, before Start(), if a certain scene is loaded or about to be (GetSceneManagerSetup() cannot be used in play mode..), or is there and i'm just not seeing it?
     
  10. LilGames

    LilGames

    Joined:
    Mar 30, 2015
    Posts:
    570
    I assume this only happens in Editor, right? (I'm experiencing the same thing and found this thread by Googling). I think the answer is to use a conditional that doesn't load the scene if it is Editor mode.

    #if !UNITY_EDITOR
     
  11. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    It was less about loading, more about checking whether something is loaded, and defines unfortunately won't help there.
    The nearest solution i think would be allowing GetSceneManagerSetup to be called in playmode (why is it even disallowed?).
     
  12. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    @Flavelius I am getting the same issue when loading in Start. Does it work for you if you run the check for isLoaded in Start?

    EDIT: I'm an idiot :) I was checking with the full path of the scene using the method SceneManager.GetSceneByName, not SceneManager.GetSceneByPath... When I do it the correct way it works :)
     
    Last edited: Jun 16, 2019
  13. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    By the way the answer i got, that in Awake the scene is technically not loaded is inconsistent with the builtin unity debug warning that there are multiple audio listeners that still gets printed even when one of those is destroyed inside Awake.
     
    Mikael-H likes this.
  14. huulong

    huulong

    Joined:
    Jul 1, 2013
    Posts:
    224
    I had the same issue today, basically I use additive scenes a lot, and I need to switch Active scene on the go, between loading and unloading.

    I'll try to synthesize our findings:

    SceneManager.GetSceneByName/Path/BuildIndex always return the first matching scene, including scenes added in the editor for testing, even if they are unloaded. And while you can add a given scene once in the editor, you can add an unlimited number of them at runtime. Besides, even if a scene has been added unloaded in the editor, loading it additively at runtime will not reuse the one you placed, but create another one.

    As a result:

    A. SceneManager.GetSceneXXX method will return any editor scene pre-added this way, which is generally useless, esp. if unloaded. So you'll need sceneCount + GetSceneAt to manually check and find the scene you want (but that only works at Start time, although I didn't check it for Unity 2022).

    B. If your game purposefully loads the same scene multiple times, you'll need to use sceneCount + GetSceneAt too (but I consider it less bad, because this is part of how your game works, it's not just something you did in the editor that added an error that wouldn't occur in a build).

    In case A., as @LilGames suggested, we can add a UNITY_EDITOR-only check, and switch to sceneCount + GetSceneAt in editor only, but that grows code for something pretty trivial... Maybe we should suggest Unity to reuse unloaded added scenes in editor the first time they are actually loaded at runtime.

    Also, the fact they return even an added scene unloaded in the editor must be a bug, so I'll report that. I'm only loading scenes much later than Start, so I don't have the same issue as the OP, so this would be enough to fix my usage case.