Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

New Multi-Scene Changes in 5.3.1p4 Issues

Discussion in 'Scripting' started by Jodon, Jan 22, 2016.

  1. Jodon

    Jodon

    Joined:
    Sep 12, 2010
    Posts:
    419
    Hello,

    I've been working on a plug-in to extend multi-scene editing functionality and the new changes to 5.3.1p4 break very desirable behaviour. I want to be able to load a scene that is NOT a part of the build when in the editor, but since I can no longer access EditorSceneManager while the game is running I can no longer do this.

    Please reconsider this functionality.
     
  2. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    Unless this new behaviour is in the changelog as a new feature or fix you should submit this to the bug tracker as a regression
     
  3. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    4,958
    It would be great if you could talk directly to a Unity dev who is working with this. I have no idea who that would be, though.

    Maybe if @karl.jones sees this he can give better direction.
     
  4. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    452
    Hi,

    @passerbycmc it is in the changelog
    Changes
    • MSE: Prevent calling some Editor mode only APIs on EditorSceneManager from play mode, including EditorSceneManager.OpenScene, EditorSceneManager.SaveScene etc.
    • MSE: Prevent calling some play mode only APIs on SceneManager from Editor mode, including SceneManager.LoadLevel, SceneManager.LoadLevelAsync etc.

    @Jodon
    The first reason is simply that you should not be using editor functions in playmode, simply because they don't exists at all in the standalone players.

    Another reason is that EditorSceneManager.OpenScene does not disconnect prefabs so opening a scene during playmode will potentially result in a lot of wrong property modifications being recorded or worse the change could accidentally be applied to the prefab asset.

    The third reason is a safety reason. By ensuring that you can only load scenes which are added to the build settings during play mode you can safely assume that the same scene can be loaded in the standalone player. If we allowed loading arbitrary you could build something that would work fine in the editor but once you deployed to a device it would be broken.

    So the question is, why do you want to load the scenes in playmode? What are you trying to achieve?
     
  5. Jodon

    Jodon

    Joined:
    Sep 12, 2010
    Posts:
    419
    Hello Steen, thanks for the reply.

    What I'm trying to achieve is splitting up levels for workflow purposes and then merging them back together during the build process. For example, you should be able to break apart static geometry from audio placement and lighting, so they all live in separate levels. Then a build script should be able to re-assemble these as if they were a single scene.

    You should be able to mimic this same behaviour when playing in the editor, so that you're aware that the scenes do not load separately and do not have to be added to the build settings. You cannot do this using PostProcessScene because that executes too late in the build process (Awake/OnEnable occur on all objects, and then PostProcessScene runs, resulting in different behaviour in the editor vs. at runtime). As a result, you must do this as one of the first Awake() calls you receive.

    In 5.3.1p2 and p3 this appeared to work correctly (there's some weird rules at the moment, where if the scenes are already open when you hit play, they remain in their current state), but exiting play mode correctly un-merged the scenes. In the new build, I get a warning that I cannot load scenes that are not apart of the build -- but that's precisely what I want to do.
     
  6. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    452
    Hi,

    I think we have talked before :)

    You would like have two things which the SceneManager API simply does not support: Loading a scene without it being in the build settings and have the loading completely synchronous. I have described why the SceneManager does not allow scenes to be loaded without them being in the build settings, but the other issues with the SceneManager is that the loading does not complete immediately, the scene is only fully loaded on the next frame, which means it would requires at least one extra frame to complete before the objects of the other scene is awoken and you can setup references.

    The EditorSceneManager OpenScene API does both the things you want but has other issues.

    So what do we do now?

    I am reluctant to have the exceptions removed again, because unless you really know what you are doing it is dangerous to call Edit Mode APIs in play mode.

    EditorApplication.LoadLevelAdditiveInPlayMode is almost what you want, but loading is still delayed one frame so you again have the issue that Awake for both scenes is not called the same in the editor and in the standalone.

    We could provide you new API which does exactly what you want with the disclaimer that loading scene not in the buildsettings can break the game you deploy to devices unless you are carefull. I will bring this up internally but it will not help you right now. (Would practically be like the EditorSceneManager APIs but would break prefab connection)

    You could require users to have a processing step, press a button in a windows you have created, which would build the scenes and setup the buildsettings. Of course this is not as nice as simply being able to enter play mode and it would just work.

    I am open to other suggestions.
     
  7. Jodon

    Jodon

    Joined:
    Sep 12, 2010
    Posts:
    419
    Hello Steen,

    Thanks for the response! We have indeed chatted before, you were kind enough to warn me of upcoming changes for my previous plug-in.

    That would indeed solve my problem, and you could throw it in the InternalEditorUtility or even the Unsupported class to discourage its use. I could also disconnect the prefabs manually once called in play mode, but I have yet to notice this issue -- can you explain how it manifests? I was previously using the internal LoadSerializedAndForget since 4.x without many issues (until 5.x scene serialization that cuts out the duplicate prefab data changed this).

    I think a satisfying fix [which I always bring up] would be for PostProcessScene to be able to execute before Awake() (but preferably after all of the data has been deserialized -- so I could Find() my objects or otherwise traverse links). There appears to be precedence for this as RuntimeInitializeOnLoadAttribute allows you to choose before or after a scene. If we could execute the EditorSceneManager.OpenScene during the PostProcessScene in the editor, it would make my desired functionality less than half as complicated.

    Related, I don't quite understand why a scene executes Awake() before it's considered loaded, yet all of the scene data exists and is deserialized. I often run into a case in my logs where gameObject.scene.isLoaded returns false -- that's something I was not expecting, is it a bug or is that intended? I've noticed this behaviour (and the ability to use SceneManger LoadScene during Awake) isn't consistent between loading directly into the scene from the Editor, or calling SceneManager LoadScene to enter the level during a play-in-editor session.

    Loosely related, I'm also having issues during the build step in PostProcessScene() (or any other function) because if I'm building a currently-open scene, the gameObject.scene ends up being a temporary scene (e.g. Temp/1.backup) and there's no way to decipher what original scene it belonged to (e.g. Level4.unity).
     
  8. Tethys

    Tethys

    Joined:
    Jul 2, 2012
    Posts:
    665
  9. Jodon

    Jodon

    Joined:
    Sep 12, 2010
    Posts:
    419
    Hello Steen,

    Any updates on your side? On mine, I am unable to load a "stripped" object (e.g. prefab) using LoadSerializedFileAndForget. This puts me in an awkward position, where scenes saved with SaveSerializedFileAndForget are not stripped, but work correctly and can be loaded by the Editor during a play session, but actual Unity scenes do not load correctly and there's still currently no way to load them during a play session.