Search Unity

Executing first scene in build settings when pressing play button in editor?

Discussion in 'Editor & General Support' started by hexdump, Nov 6, 2012.

  1. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    Hi!,

    Is there anyway to execute first scene that has been specified in build settings (the first scene game will load when in production) when I press play button (or whatever short-cut) in unity editor?.

    The problem is that I have an startup scene that inits everything before entering the first real scene. This startup scene creates some objects that will live all game and it is a bit of a pain to:

    1) Save current editing scene

    2) Find startup scene

    3) Load startup scene

    4) Press play

    5) Get to the scene I was editing

    This has to be done for every little change I do in a scene in the game. I know steps 4 and 5 can't be avoid obviously, but what about from 1 to 3. Is there anyway to let unity run scenes in the order they appear in the building settings when executing in editor?.

    Thanks in advance.
     
    Roman200333 and illustir like this.
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It is not directly possible as far as I know. You may create a manager that checks a simple boolean if the startup scene was executed, if not, simply load it by script.
     
  3. Dreamwriter

    Dreamwriter

    Joined:
    Jul 22, 2011
    Posts:
    472
    Yeah, this is an annoyance in Unity, the game my team worked on for the last year had the exact same issue, it did all of its initialization in the title scene, but more than half the time we were editing a different scene. Unfortunately, there really is no way to make it do what you want, what Dantus suggested is the best idea, have a GameObject in each scene with a script that checks a static variable and based on the results it loads the first scene which sets that variable.
     
  4. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    Is there any possibility to run the game through code? I mean, perhaps one solution could be to write a script editor that we could run with a shortcut that enters plays mode selecting the scene we want to execute.
     
  5. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
  6. Batigol

    Batigol

    Joined:
    Oct 17, 2012
    Posts:
    234
    YOu can make a master scene and player will chose scene to player from there
     
  7. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    Too much hashle mate. Here a script that does exactly what I need:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5.  
    6. class EditorScrips : EditorWindow
    7. {
    8.  
    9.     [MenuItem("Play/PlayMe _%h")]
    10.     public static void RunMainScene()
    11.     {
    12.         EditorApplication.OpenScene("Assets/MainScene.unity");
    13.         EditorApplication.isPlaying = true;
    14.     }
    15. }
    16.  
    In this particular case you have an editor script that loads MainScene when Ctrl-H is pressed or item is clicked on the menu bar.
     
    Last edited: Nov 6, 2012
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Awesome! Wasn't aware that this is possible directly in the editor!
     
  9. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    Neither do I, just came across it reading your comments :).
     
  10. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    For anyone interested, I have added a bit of code to be able to run the main scene and then return to the one I was editing. For me it is pretty useful :):

    Code (csharp):
    1.  
    2.     [MenuItem("Play/Execute starting scene _%h")]
    3.     public static void RunMainScene()
    4.     {
    5.         string currentSceneName=EditorApplication.currentScene;
    6.         File.WriteAllText(".lastScene",currentSceneName);
    7.         EditorApplication.OpenScene("Assets/Scene/MainMenu.unity");
    8.         EditorApplication.isPlaying = true;
    9.     }
    10.    
    11.     [MenuItem("Play/Reload editing scnee _%g")]
    12.     public static void ReturnToLastScene()
    13.     {
    14.         string lastScene=File.ReadAllText(".lastScene");
    15.         EditorApplication.OpenScene(lastScene);
    16.     }
    17.  
     
  11. pankao

    pankao

    Joined:
    Feb 18, 2013
    Posts:
    18
    Hey! Thanks for your efford guys, this is f**king useful for everyone i bet;)
     
  12. archivision

    archivision

    Joined:
    Jun 17, 2009
    Posts:
    91
    you can also use the same button..

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5. using System.IO;
    6.  
    7. class EditorScrips : EditorWindow
    8. {
    9.     [MenuItem("Play/PlayMe _%h")]
    10.  
    11.     public static void RunMainScene()
    12.     {
    13.         if (!EditorApplication.isPlaying)
    14.         {
    15.             string currentSceneName = EditorApplication.currentScene;
    16.             File.WriteAllText(".lastScene", currentSceneName);
    17.  
    18.             EditorApplication.OpenScene("Assets/Scene/MainMenu.unity");
    19.             EditorApplication.isPlaying = true;
    20.         }
    21.         if (EditorApplication.isPlaying)
    22.         {
    23.             string lastScene = File.ReadAllText(".lastScene");
    24.             EditorApplication.isPlaying = false;
    25.             EditorApplication.OpenScene(lastScene);
    26.         }
    27.     }
    28. }
     
    aimansarie likes this.
  13. yoyo

    yoyo

    Joined:
    Apr 16, 2010
    Posts:
    112
    I took this idea and ran with it to build a SceneAutoLoader script which I put on the Unity wiki:
    http://wiki.unity3d.com/index.php/SceneAutoLoader

    My version:
    • integrates with the standard editor play button
    • lets you select which "master scene" to use
    • can be turned on and off
    • lets you save your sub-scene before auto-loading the master scene
    • takes about 5 times as much code :)
    I hope it's useful, enjoy!
     
  14. cesarpo

    cesarpo

    Joined:
    Jun 8, 2013
    Posts:
    97
    This makes me question how people is using unity, since this functionality isn't already in... because I find this extremely useful! Thanks!
     
  15. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
    Its funny to stumble about this Thread , because i build one script like this for myself a weak ago :) .
     
  16. RoobrArcade

    RoobrArcade

    Joined:
    Sep 24, 2013
    Posts:
    2
    Thank you!!!
     
  17. TicTac

    TicTac

    Joined:
    Oct 30, 2012
    Posts:
    2
    Really useful, thanks!
     
  18. helios

    helios

    Joined:
    Oct 5, 2009
    Posts:
    308
    Seriously, makes me wonder if I'm just doing things completely wrong?? How come more people don't have this issue?

    Also, amazing script - thanks!
     
  19. Jeff-Kesselman

    Jeff-Kesselman

    Joined:
    Apr 5, 2010
    Posts:
    99
    Very useful thank you. really something Unity should just bundle in.
     
    ForMiSoft likes this.
  20. elecorn

    elecorn

    Joined:
    Jul 15, 2012
    Posts:
    2
    You are my hero!
     
  21. AhrenM

    AhrenM

    Joined:
    Aug 30, 2014
    Posts:
    74
  22. inferno222

    inferno222

    Joined:
    Apr 29, 2014
    Posts:
    6
    Finally i got the unofficial patch for this excellent script :D, Since now you need to use EditorSceneManager and SceneManger :OO, i hope someone find this useful and someone makes this script even better :D

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.SceneManagement;
    4. using UnityEditor;
    5. using UnityEditor.SceneManagement;
    6.  
    7. /// <summary>
    8. /// Scene auto loader.
    9. /// </summary>
    10. /// <description>
    11. /// This class adds a File > Scene Autoload menu containing options to select
    12. /// a "master scene" enable it to be auto-loaded when the user presses play
    13. /// in the editor. When enabled, the selected scene will be loaded on play,
    14. /// then the original scene will be reloaded on stop.
    15. ///
    16. /// Based on an idea on this thread:
    17. /// http://forum.unity3d.com/threads/157502-Executing-first-scene-in-build-settings-when-pressing-play-button-in-editor
    18. /// </description>
    19. [InitializeOnLoad]
    20. public static class SceneAutoLoader
    21. {
    22.     // Static constructor binds a playmode-changed callback.
    23.     // [InitializeOnLoad] above makes sure this gets execusted.
    24.     static SceneAutoLoader()
    25.     {
    26.         EditorApplication.playmodeStateChanged += OnPlayModeChanged;
    27.     }
    28.  
    29.     // Menu items to select the "master" scene and control whether or not to load it.
    30.     [MenuItem("File/Scene Autoload/Select Master Scene...")]
    31.     private static void SelectMasterScene()
    32.     {
    33.         string masterScene = EditorUtility.OpenFilePanel("Select Master Scene", Application.dataPath, "unity");
    34.         if (!string.IsNullOrEmpty(masterScene))
    35.         {
    36.             MasterScene = masterScene;
    37.             LoadMasterOnPlay = true;
    38.         }
    39.     }
    40.  
    41.     [MenuItem("File/Scene Autoload/Load Master On Play", true)]
    42.     private static bool ShowLoadMasterOnPlay()
    43.     {
    44.         return !LoadMasterOnPlay;
    45.     }
    46.     [MenuItem("File/Scene Autoload/Load Master On Play")]
    47.     private static void EnableLoadMasterOnPlay()
    48.     {
    49.         LoadMasterOnPlay = true;
    50.     }
    51.  
    52.     [MenuItem("File/Scene Autoload/Don't Load Master On Play", true)]
    53.     private static bool ShowDontLoadMasterOnPlay()
    54.     {
    55.         return LoadMasterOnPlay;
    56.     }
    57.     [MenuItem("File/Scene Autoload/Don't Load Master On Play")]
    58.     private static void DisableLoadMasterOnPlay()
    59.     {
    60.         LoadMasterOnPlay = false;
    61.     }
    62.  
    63.     // Play mode change callback handles the scene load/reload.
    64.     private static void OnPlayModeChanged()
    65.     {
    66.         if (!LoadMasterOnPlay) return;
    67.  
    68.         if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode)
    69.         {
    70.             // User pressed play -- autoload master scene.
    71.             PreviousScene = EditorSceneManager.GetActiveScene().name;
    72.             if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
    73.             {
    74.                 EditorSceneManager.OpenScene(MasterScene, OpenSceneMode.Single);
    75.             }
    76.             else
    77.             {
    78.                 // User cancelled the save operation -- cancel play as well.
    79.                 EditorApplication.isPlaying = false;
    80.             }
    81.         }
    82.         if (EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode)
    83.         {
    84.             // User pressed stop -- reload previous scene.
    85.             if (SceneAutoLoader.PreviousScene != SceneAutoLoader.MasterScene)
    86.                 EditorApplication.update += ReloadLastScene;
    87.         }
    88.     }
    89.  
    90.     public static void ReloadLastScene()
    91.     {
    92.         Debug.Log("Reloading..");
    93.         if (EditorSceneManager.GetActiveScene().name != SceneAutoLoader.PreviousScene)
    94.         {
    95.             EditorSceneManager.LoadScene(SceneAutoLoader.PreviousScene);
    96.             EditorApplication.update -= ReloadLastScene;
    97.         }
    98.     }
    99.  
    100.     // Properties are remembered as editor preferences.
    101.     private const string cEditorPrefLoadMasterOnPlay = "SceneAutoLoader.LoadMasterOnPlay";
    102.     private const string cEditorPrefMasterScene = "SceneAutoLoader.MasterScene";
    103.     private const string cEditorPrefPreviousScene = "SceneAutoLoader.PreviousScene";
    104.  
    105.     public static bool LoadMasterOnPlay
    106.     {
    107.         get { return EditorPrefs.GetBool(cEditorPrefLoadMasterOnPlay, false); }
    108.         set { EditorPrefs.SetBool(cEditorPrefLoadMasterOnPlay, value); }
    109.     }
    110.  
    111.     private static string MasterScene
    112.     {
    113.         get { return EditorPrefs.GetString(cEditorPrefMasterScene, "Master.unity"); }
    114.         set { EditorPrefs.SetString(cEditorPrefMasterScene, value); }
    115.     }
    116.  
    117.     private static string _previousScene;
    118.  
    119.     public static string PreviousScene
    120.     {
    121.         get { return EditorPrefs.GetString(cEditorPrefPreviousScene, _previousScene); }
    122.         set
    123.         {
    124.             _previousScene = value;
    125.             EditorPrefs.SetString(cEditorPrefPreviousScene, value);
    126.         }
    127.     }
    128. }
    129.  
    If its desirable to check for MasterScene and PreviousScene existence this part of the code can be change (Haven't Tested though, but it should work)

    Code (CSharp):
    1.  
    2. if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode)
    3. {
    4.     // User pressed play -- autoload master scene.
    5.     PreviousScene = EditorSceneManager.GetActiveScene().name;
    6.     if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
    7.     {
    8.         // If master scene exist, opens that scene
    9.         foreach (Scene scene in EditorSceneManager.GetAllScenes())
    10.         {
    11.             if (scene.name == MasterScene)
    12.             {
    13.                 EditorSceneManager.OpenScene(MasterScene, OpenSceneMode.Single);
    14.                 return;
    15.             }
    16.         }
    17.         //Else cancel play and throw error
    18.         Debug.LogError(string.Format("error: scene not found: {0}", MasterScene));
    19.         EditorApplication.isPlaying = false;
    20.     }
    21.     else
    22.     {
    23.         // User cancelled the save operation -- cancel play as well.
    24.         EditorApplication.isPlaying = false;
    25.     }
    26. }
    27. else if (EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode)
    28. {
    29.     // User pressed stop .
    30.     // If previous scene exist add ReloadLastScene to editors update
    31.     foreach (Scene scene in EditorSceneManager.GetAllScenes())
    32.     {
    33.         if (scene.name == PreviousScene)
    34.         {
    35.             if (SceneAutoLoader.PreviousScene != SceneAutoLoader.MasterScene)
    36.                 EditorApplication.update += ReloadLastScene;
    37.             return;
    38.         }
    39.     }
    40.     //Else throw error
    41.     Debug.LogError(string.Format("error: scene not found: {0}", PreviousScene));
    42. }
    43.  
     
    Last edited: Dec 18, 2015
    Dantus likes this.
  23. oneuppedgames

    oneuppedgames

    Joined:
    Jul 30, 2013
    Posts:
    15
    @inferno222 Thank you for the update on the script. It seems to work when loading the MasterScene. However, when I go back to my editor (so when I cancel Play-mode), the PreviousScene is loaded and then immediately replaced by the MasterScene.

    So it's like this:
    - I setup the Script using, adding the MasterScene via File -> Scene Autoload
    - I execute my game (using the Play button) within my PreviousScene
    - The game starts with the MasterScene (hurray!)
    - I press the Play button once again to cancel the run
    - The game stops, switches to the PreviousScene and the immediately to the MasterScene
    - The hierarchy shows a weird overview of my two scenes (see screenshots) and the ReloadLastScene void gets called twice (see Loading... in debug).

    Any idea? I'm running the latest Unity Pro on OSX 10.11.12
     

    Attached Files:

    Last edited: Feb 4, 2016
    gregory_igromatic likes this.
  24. oneuppedgames

    oneuppedgames

    Joined:
    Jul 30, 2013
    Posts:
    15
    I've changed the script a bit to my needs (it's very very basic now, but it works with no hassle). It's not super-perfect, but it does what it does. If anyone needs it:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEditor.SceneManagement;
    5.  
    6. [InitializeOnLoad]
    7. public static class LoadMainScene
    8. {
    9.     static LoadMainScene ()
    10.     {
    11.         EditorApplication.playmodeStateChanged += OnPlayModeChanged;
    12.     }
    13.      
    14.     private static void OnPlayModeChanged ()
    15.     {
    16.         if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode) {
    17.             if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo ()) {
    18.                 EditorSceneManager.OpenScene ("Assets/Scenes/PUT_MAIN_SCENE_NAME_HERE.unity");
    19.                 EditorApplication.isPlaying = true;
    20.             } else {
    21.                 EditorApplication.isPlaying = false;
    22.             }
    23.         }
    24.  
    25.         if (!EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode) {
    26.             EditorApplication.isPlaying = false;
    27.             EditorSceneManager.OpenScene ("Assets/Scenes/PUT_WORKING_SCENE_NAME_HERE.unity");
    28.         }
    29.     }
    30. }
     
  25. npritchard

    npritchard

    Joined:
    Oct 7, 2012
    Posts:
    10
    Reloading previous scene didn't work for me, it was happening too early. I changed the code so that reload happens *after* return to edit mode:

    Code (CSharp):
    1.  
    2.   // Play mode change callback handles the scene load/reload.
    3.   private static void OnPlayModeChanged() {
    4.     if (!LoadMasterOnPlay) return;
    5.  
    6.     if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode) {
    7.       // User pressed play -- autoload master scene.
    8.       PreviousScene = EditorSceneManager.GetActiveScene().name;
    9.       if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) {
    10.         EditorSceneManager.OpenScene(MasterScene, OpenSceneMode.Single);
    11.       } else {
    12.         // User cancelled the save operation -- cancel play as well.
    13.         EditorApplication.isPlaying = false;
    14.       }
    15.     }
    16.     if (!EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode) {
    17.       // User pressed stop -- reload previous scene.
    18.       if (SceneAutoLoader.PreviousScene != SceneAutoLoader.MasterScene)
    19.         EditorApplication.update += ReloadLastScene;
    20.     }
    21.   }
    22.  
    23.   public static void ReloadLastScene() {
    24.     Debug.Log("Reloading..");
    25.     if (EditorSceneManager.GetActiveScene().name != SceneAutoLoader.PreviousScene) {
    26.       EditorSceneManager.OpenScene("Assets/" + SceneAutoLoader.PreviousScene + ".unity", OpenSceneMode.Single);
    27.     }
    28.     EditorApplication.update -= ReloadLastScene;
    29.   }
     
  26. pixelminer

    pixelminer

    Joined:
    Jul 24, 2011
    Posts:
    26
    Made it so scene paths are used and the scene is loaded after the editor is fully out of play mode. Use this. It will work as expected.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.SceneManagement;
    4. using UnityEditor;
    5. using UnityEditor.SceneManagement;
    6. /// <summary>
    7. /// Scene auto loader.
    8. /// </summary>
    9. /// <description>
    10. /// This class adds a File > Scene Autoload menu containing options to select
    11. /// a "master scene" enable it to be auto-loaded when the user presses play
    12. /// in the editor. When enabled, the selected scene will be loaded on play,
    13. /// then the original scene will be reloaded on stop.
    14. ///
    15. /// Based on an idea on this thread:
    16. /// http://forum.unity3d.com/threads/157502-Executing-first-scene-in-build-settings-when-pressing-play-button-in-editor
    17. /// </description>
    18. [InitializeOnLoad]
    19. public static class SceneAutoLoader
    20. {
    21.     // Static constructor binds a playmode-changed callback.
    22.     // [InitializeOnLoad] above makes sure this gets execusted.
    23.     static SceneAutoLoader()
    24.     {
    25.         EditorApplication.playmodeStateChanged += OnPlayModeChanged;
    26.     }
    27.     // Menu items to select the "master" scene and control whether or not to load it.
    28.     [MenuItem("File/Scene Autoload/Select Master Scene...")]
    29.     private static void SelectMasterScene()
    30.     {
    31.         string masterScene = EditorUtility.OpenFilePanel("Select Master Scene", Application.dataPath, "unity");
    32.         if (!string.IsNullOrEmpty(masterScene))
    33.         {
    34.             MasterScene = masterScene;
    35.             LoadMasterOnPlay = true;
    36.         }
    37.     }
    38.     [MenuItem("File/Scene Autoload/Load Master On Play", true)]
    39.     private static bool ShowLoadMasterOnPlay()
    40.     {
    41.         return !LoadMasterOnPlay;
    42.     }
    43.     [MenuItem("File/Scene Autoload/Load Master On Play")]
    44.     private static void EnableLoadMasterOnPlay()
    45.     {
    46.         LoadMasterOnPlay = true;
    47.     }
    48.     [MenuItem("File/Scene Autoload/Don't Load Master On Play", true)]
    49.     private static bool ShowDontLoadMasterOnPlay()
    50.     {
    51.         return LoadMasterOnPlay;
    52.     }
    53.     [MenuItem("File/Scene Autoload/Don't Load Master On Play")]
    54.     private static void DisableLoadMasterOnPlay()
    55.     {
    56.         LoadMasterOnPlay = false;
    57.     }
    58.     // Play mode change callback handles the scene load/reload.
    59.     private static void OnPlayModeChanged()
    60.     {
    61.         if (!LoadMasterOnPlay) return;
    62.         if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode)
    63.         {
    64.             // User pressed play -- autoload master scene.
    65.             PreviousScene = EditorSceneManager.GetActiveScene().path;
    66.             if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
    67.             {
    68.                 EditorSceneManager.OpenScene(MasterScene, OpenSceneMode.Single);
    69.             }
    70.             else
    71.             {
    72.                 // User cancelled the save operation -- cancel play as well.
    73.                 EditorApplication.isPlaying = false;
    74.             }
    75.         }
    76.         if (EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode)
    77.         {
    78.             // User pressed stop -- reload previous scene.
    79.             if (SceneAutoLoader.PreviousScene != SceneAutoLoader.MasterScene)
    80.                 EditorApplication.update += ReloadLastScene;
    81.         }
    82.     }
    83.     public static void ReloadLastScene()
    84.     {
    85.         Debug.Log("Reloading..");
    86.         if (!EditorApplication.isPlaying && EditorSceneManager.GetActiveScene().path != SceneAutoLoader.PreviousScene)
    87.         {
    88.             EditorSceneManager.LoadScene(SceneAutoLoader.PreviousScene);
    89.             EditorApplication.update -= ReloadLastScene;
    90.         }
    91.     }
    92.     // Properties are remembered as editor preferences.
    93.     private const string cEditorPrefLoadMasterOnPlay = "SceneAutoLoader.LoadMasterOnPlay";
    94.     private const string cEditorPrefMasterScene = "SceneAutoLoader.MasterScene";
    95.     private const string cEditorPrefPreviousScene = "SceneAutoLoader.PreviousScene";
    96.     public static bool LoadMasterOnPlay
    97.     {
    98.         get { return EditorPrefs.GetBool(cEditorPrefLoadMasterOnPlay, false); }
    99.         set { EditorPrefs.SetBool(cEditorPrefLoadMasterOnPlay, value); }
    100.     }
    101.     private static string MasterScene
    102.     {
    103.         get { return EditorPrefs.GetString(cEditorPrefMasterScene, "Master.unity"); }
    104.         set { EditorPrefs.SetString(cEditorPrefMasterScene, value); }
    105.     }
    106.     private static string _previousScene;
    107.     public static string PreviousScene
    108.     {
    109.         get { return EditorPrefs.GetString(cEditorPrefPreviousScene, _previousScene); }
    110.         set
    111.         {
    112.             _previousScene = value;
    113.             EditorPrefs.SetString(cEditorPrefPreviousScene, value);
    114.         }
    115.     }
    116. }
    117.  
     
    Marrt, shaneparsons and MV10 like this.
  27. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    I'm kind of amazed something like this isn't built into Unity yet.

    Minor bug, as written above, line 88 results in: InvalidOperationException: This can only be used during play mode, please use EditorSceneManager.OpenScene() instead.

    Changing it to OpenScene fixes it.
     
    shaneparsons and Dave-Carlile like this.
  28. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    @pixelminer -- I managed to get a login to the Unity Wiki, mind if I update it with your version of this?
     
  29. DarkGate

    DarkGate

    Joined:
    Jan 26, 2016
    Posts:
    33
    Latest script from pixelminer with the tweak mentioned by MV10 works for me. Thanks guys!
     
    shaneparsons likes this.
  30. magnetix_sg

    magnetix_sg

    Joined:
    Mar 12, 2015
    Posts:
    1
    I have a small fix. Inside OnPlayModeChanged(), the comparison would sometimes pass when it shouldn't because Master takes the full disk location whereas Previous only takes the project path. The fix is a small string operation as follows:

    Code (CSharp):
    1.     // User pressed stop -- reload previous scene.
    2.     if ((SceneAutoLoader.PreviousScene != SceneAutoLoader.MasterScene)
    3.         && (!SceneAutoLoader.MasterScene.EndsWith(SceneAutoLoader.PreviousScene)) )
    4.  
    An improvement I'd love to make to this script would be to allow reloading multiple scenes, since that is common workflow with the new SceneManager. If I get around to it I'll update this thread, but I don't think it will be soon. Anyway it's already a huge improvement for my project. Big thanks to those involved!
     
  31. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    I rewrote the script for my own purpose. It now just uses a shortcut "Ctrl+0" and a SelectMasterScene menu-item. It also ensures that you will get back to the previous-scene regardless of whether you press stop or use the shortcut to stop play-mode.

    Short:
    - Press CTRL+0 to start play-mode from your master scene; you will return to edit-scene once play-mode has stopped

    Here is the script, have fun.
    StartFromMasterScene.cs:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using UnityEditor.SceneManagement;
    5.  
    6. //Marrt's modification of the SceneAutoLoader based on these scripts:
    7.     //http://forum.unity3d.com/threads/executing-first-scene-in-build-settings-when-pressing-play-button-in-editor.157502/
    8.     //http://answers.unity3d.com/questions/441246/editor-script-to-make-play-always-jump-to-a-start.html
    9. //
    10. //    put this script into Assets/Editor/ or it won't show up
    11.  
    12. [InitializeOnLoad]
    13. static class StartFromMasterScene{
    14.  
    15.     private    const string shortcut = "%0";
    16.  
    17.     //static constructor subscribes to event (this is the reason for [InitializeOnLoad] at the top)  
    18.     static StartFromMasterScene(){    EditorApplication.playmodeStateChanged += ReloadIfPlayModeHasStopped;    }
    19.  
    20.     static void ReloadIfPlayModeHasStopped() {
    21.  
    22.         if( EditorApplication.isPlayingOrWillChangePlaymode )    { return;    }    // we are only interested in playmode-stop
    23.         if (!StartedPerShortcut)                                { return;    }    // if we didn't start per shortcut, there is nothing to do here
    24.              
    25.         if(!EditorApplication.isPlaying){
    26.             EditorSceneManager.OpenScene(PreviousScenePath);    //reload previous scene
    27.             StartedPerShortcut = false;                            //reset
    28.         }
    29.     }
    30.  
    31.     [MenuItem("Edit/StartFromMasterScene/Play "+shortcut)]
    32.     public static void PlayFromMasterScene(){
    33.  
    34.         //Load Master before play-mode starts
    35.         if ( !EditorApplication.isPlaying == true ){
    36.          
    37.             // kindly ask for scene save
    38.             if(!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) {return;} //abort if canceled
    39.  
    40.             PreviousScenePath = EditorSceneManager.GetActiveScene().path;    // save PATH of current scene (LoadScene needs name, OpenScene needs path)          
    41.             EditorSceneManager.OpenScene(MasterScenePath);                    // open Master scene before starting          
    42.             EditorApplication.isPlaying = true;                                // start
    43.             StartedPerShortcut = true;                                        // remember that we started per shortcut
    44.          
    45.             Debug.Log("Previous" +PreviousScenePath);
    46.          
    47.         //shortcut can be used as stop-button while play-mode is active
    48.         }else{
    49.             EditorApplication.isPlaying = false;
    50.         }
    51.     }
    52.  
    53. //    Menu item to choose the path of the master-scene
    54.     [MenuItem("Edit/StartFromMasterScene/Select Master Scene...")]
    55.     private static void SelectMasterScene(){
    56.         string masterScene = EditorUtility.OpenFilePanel("Select Master Scene", Application.dataPath, "unity");
    57.         if (!string.IsNullOrEmpty(masterScene)){
    58.             MasterScenePath = masterScene;
    59.         }
    60.     }
    61.  
    62.     // Properties need to be remembered as editor preferences, otherwise they would be lost between playmode on-offs
    63.  
    64.     //path of master scene
    65.     private const string cEditorPrefMasterScene = "SceneAutoLoader.MasterScene";  
    66.     private static string MasterScenePath{
    67.         get { return EditorPrefs.GetString(cEditorPrefMasterScene, "none"); }
    68.         set { EditorPrefs.SetString(cEditorPrefMasterScene, value); }
    69.     }
    70.  
    71.     //path of previous scene
    72.     private const string cEditorPrefPreviousScene = "SceneAutoLoader.PreviousScenePath";
    73.     private static string PreviousScenePath{
    74.         get { return EditorPrefs.GetString(cEditorPrefPreviousScene, "none"); }
    75.         set { EditorPrefs.SetString(cEditorPrefPreviousScene, value); }
    76.     }
    77.  
    78.     //remember if editor started per shortcut
    79.     private const string cEditorPrefStartedPerShortcut = "SceneAutoLoader.StartedPerShortcut";
    80.     private static bool StartedPerShortcut{
    81.         get { return EditorPrefs.GetBool(cEditorPrefStartedPerShortcut, false); }
    82.         set { EditorPrefs.SetBool(cEditorPrefStartedPerShortcut, value); }
    83.     }
    84. }
    85.  

    Edit: changed script to stop loading another scene if user pressed [cancel] on save-scene-dialog
     
    Last edited: Aug 16, 2016
  32. AhrenM

    AhrenM

    Joined:
    Aug 30, 2014
    Posts:
    74
    Hi all,

    A variant on this for those are big into additive scenes. This one will persist whatever scenes you had loaded into the editor as well as the active scene and restore them all correctly when you exit play mode. I also updated the persistence function to support setting for multiple projects.

    A.
     

    Attached Files:

    alxcancado and anisabboud like this.
  33. Kalms

    Kalms

    Joined:
    Nov 18, 2016
    Posts:
    4
    Hi,

    I have continued working on AhrenM's script (thanks!) and ended up with something that has stricter requirements on all GameObjects/Components (they must behave well if they go through an Awake/OnEnable/OnDisable/OnDestroy sequence), but on the other hand the entire editor UI state is preserved. Implementation here: https://github.com/falldamagestudio/UnityTools/tree/master/SceneAutoLoader
     
    AhrenM likes this.
  34. AhrenM

    AhrenM

    Joined:
    Aug 30, 2014
    Posts:
    74
    @Kalms
    I'm going to try and work out how to improve your version, but I'm not sure I'm going succeed ;-)
     
  35. Colludium

    Colludium

    Joined:
    Jan 9, 2014
    Posts:
    1
    @Kalms - thank you for that - it's excellent!
     
  36. Reshima

    Reshima

    Joined:
    Dec 10, 2012
    Posts:
    51
    @Kalms Your solution has been working for me but the fact that the current scene is loaded first became a problem (as you mentioned in your disclaimer). Basically, if anything in the current scene depends on the autoloaded scene then it will fail. This was the whole point of having an autoloaded scene for me.
     
  37. PNUMIA-Rob

    PNUMIA-Rob

    Joined:
    Jan 7, 2015
    Posts:
    33
    Holy-moly! :cool: What a time saver!
     
  38. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    That moment when you realized you've been Unity wrong all this time...

    :D
     
  39. feds

    feds

    Joined:
    Nov 8, 2017
    Posts:
    8
    Hey Guys! Thank you for your help, I did some changes and it worked great for me. I wanted to to load the scene when you press the Standard Unity button, and when you stop I wanted to back automatically to the last Scene so I grabbed some ideas here to create this solution:

    Code (CSharp):
    1. using System.IO;
    2. using UnityEditor;
    3.  
    4. /*
    5. Created by Fernando Bonet
    6. */
    7.  
    8. // ensure class initializer is called whenever scripts recompile
    9. [InitializeOnLoadAttribute]
    10. public static class PlayModeListener
    11. {
    12.     // register an event handler when the class is initialized
    13.     static PlayModeListener()
    14.     {
    15.         EditorApplication.playModeStateChanged += LogPlayModeState;
    16.     }
    17.  
    18.     private static void LogPlayModeState(PlayModeStateChange state)
    19.     {
    20.         switch (state)
    21.         {
    22.             case PlayModeStateChange.EnteredEditMode:
    23.                 OpenLastScene();
    24.                 break;
    25.             case PlayModeStateChange.ExitingEditMode:
    26.                 RunMainScene();
    27.                 break;
    28.             default:
    29.                 break;
    30.         }
    31.     }
    32.  
    33.     private static void OpenLastScene()
    34.     {
    35.         string lastScene = File.ReadAllText(".lastScene");
    36.         EditorApplication.OpenScene(lastScene);
    37.     }
    38.  
    39.     public static void RunMainScene()
    40.     {
    41.         string currentSceneName = EditorApplication.currentScene;
    42.         File.WriteAllText(".lastScene", currentSceneName);
    43.         EditorApplication.OpenScene(Scenes.ScenesPath + Scenes.Global + ".unity");
    44.         EditorApplication.isPlaying = true;
    45.     }
    46. }
     
  40. victorMaje

    victorMaje

    Joined:
    Jan 7, 2013
    Posts:
    6
    Thank you thank you thank you!!!
     
  41. Dynamite3D

    Dynamite3D

    Joined:
    Oct 26, 2016
    Posts:
    101
    I made this simple script that loads the scene at index 0 in the build settings when you push Play. I hope someone find it useful.

    It detects when the play button is push and load the scene. Then, everything comes back to normal.

    Oh! And it automatically executes itself after opening Unity and after compile scripts, so never mind about execute it. Simply put it on a Editor folder and it works.

    Code (CSharp):
    1.  
    2.     #if UNITY_EDITOR
    3.     using UnityEditor;
    4.     using UnityEditor.SceneManagement;
    5.    
    6.     [InitializeOnLoadAttribute]
    7.     public static class DefaultSceneLoader
    8.     {
    9.         static DefaultSceneLoader(){
    10.             EditorApplication.playModeStateChanged += LoadDefaultScene;
    11.         }
    12.    
    13.         static void LoadDefaultScene(PlayModeStateChange state){
    14.             if (state == PlayModeStateChange.ExitingEditMode) {
    15.                 EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo ();
    16.             }
    17.  
    18.             if (state == PlayModeStateChange.EnteredPlayMode) {
    19.                 EditorSceneManager.LoadScene (0);
    20.             }
    21.         }
    22.     }
    23.     #endif
    24.  
     
  42. dfraska

    dfraska

    Joined:
    Mar 1, 2018
    Posts:
    3
    Here's my edits to the SceneAutoLoader that handles multiple previous scenes (still only a single master scene):
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4. using System;
    5. using System.Collections.Generic;
    6.  
    7. /// <summary>
    8. /// Scene auto loader.
    9. /// </summary>
    10. /// <description>
    11. /// This class adds a File > Scene Autoload menu containing options to select
    12. /// a "master scene" enable it to be auto-loaded when the user presses play
    13. /// in the editor. When enabled, the selected scene will be loaded on play,
    14. /// then the original scene will be reloaded on stop.
    15. ///
    16. /// Based on an idea on this thread:
    17. /// http://forum.unity3d.com/threads/157502-Executing-first-scene-in-build-settings-when-pressing-play-button-in-editor
    18. /// </description>
    19. [InitializeOnLoad]
    20. static class SceneAutoLoader
    21. {
    22.     // Static constructor binds a playmode-changed callback.
    23.     // [InitializeOnLoad] above makes sure this gets executed.
    24.     static SceneAutoLoader() {
    25.         EditorApplication.playModeStateChanged += OnPlayModeChanged;
    26.     }
    27.  
    28.     // Menu items to select the "master" scene and control whether or not to load it.
    29.     [MenuItem("File/Scene Autoload/Select Master Scene...")]
    30.     private static void SelectMasterScene() {
    31.         string masterScene = EditorUtility.OpenFilePanel("Select Master Scene", Application.dataPath, "unity");
    32.         masterScene = masterScene.Replace(Application.dataPath, "Assets");  //project relative instead of absolute path
    33.         if (!string.IsNullOrEmpty(masterScene)) {
    34.             MasterScene = masterScene;
    35.             LoadMasterOnPlay = true;
    36.         }
    37.     }
    38.  
    39.     [MenuItem("File/Scene Autoload/Load Master On Play", true)]
    40.     private static bool ShowLoadMasterOnPlay() {
    41.         return !LoadMasterOnPlay;
    42.     }
    43.     [MenuItem("File/Scene Autoload/Load Master On Play")]
    44.     private static void EnableLoadMasterOnPlay() {
    45.         LoadMasterOnPlay = true;
    46.     }
    47.  
    48.     [MenuItem("File/Scene Autoload/Don't Load Master On Play", true)]
    49.     private static bool ShowDontLoadMasterOnPlay() {
    50.         return LoadMasterOnPlay;
    51.     }
    52.     [MenuItem("File/Scene Autoload/Don't Load Master On Play")]
    53.     private static void DisableLoadMasterOnPlay() {
    54.         LoadMasterOnPlay = false;
    55.     }
    56.  
    57.     // Play mode change callback handles the scene load/reload.
    58.     private static void OnPlayModeChanged(PlayModeStateChange state) {
    59.         if (!LoadMasterOnPlay) {
    60.             return;
    61.         }
    62.  
    63.         if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode) {
    64.             // User pressed play -- autoload master scene.
    65.             SetPreviousScenes();
    66.             if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) {
    67.                 try {
    68.                     EditorSceneManager.OpenScene(MasterScene);
    69.                 } catch {
    70.                     Debug.LogError(string.Format("error: scene not found: {0}", MasterScene));
    71.                     EditorApplication.isPlaying = false;
    72.  
    73.                 }
    74.             } else {
    75.                 // User cancelled the save operation -- cancel play as well.
    76.                 EditorApplication.isPlaying = false;
    77.             }
    78.         }
    79.  
    80.         // isPlaying check required because cannot OpenScene while playing
    81.         if (!EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode) {
    82.             // User pressed stop -- reload previous scenes.
    83.             foreach (var scene in PreviousScenes) {
    84.                 try {
    85.                     EditorSceneManager.OpenScene(scene, OpenSceneMode.Additive);
    86.                 } catch {
    87.                     Debug.LogError(string.Format("Error: scene not found: {0}", scene));
    88.                 }
    89.             }
    90.  
    91.         }
    92.     }
    93.  
    94.     private static void SetPreviousScenes() {
    95.         var scenes = new List<string>();
    96.         for (int i = 0; i < EditorSceneManager.sceneCount; i++) {
    97.             scenes.Add(EditorSceneManager.GetSceneAt(i).path);
    98.         }
    99.  
    100.         PreviousScenes = scenes.ToArray();
    101.     }
    102.  
    103.     // Properties are remembered as editor preferences.
    104.     private const string cEditorPrefLoadMasterOnPlay = "SceneAutoLoader.LoadMasterOnPlay";
    105.     private const string cEditorPrefMasterScene = "SceneAutoLoader.MasterScene";
    106.     private const string cEditorPrefPreviousScenes = "SceneAutoLoader.PreviousScenes";
    107.  
    108.     private static bool LoadMasterOnPlay {
    109.         get { return EditorPrefs.GetBool(cEditorPrefLoadMasterOnPlay, false); }
    110.         set { EditorPrefs.SetBool(cEditorPrefLoadMasterOnPlay, value); }
    111.     }
    112.  
    113.     private static string MasterScene {
    114.         get { return EditorPrefs.GetString(cEditorPrefMasterScene, "Master.unity"); }
    115.         set { EditorPrefs.SetString(cEditorPrefMasterScene, value); }
    116.     }
    117.  
    118.     private static string[] PreviousScenes {
    119.         get { return EditorPrefs.GetString(cEditorPrefPreviousScenes, EditorSceneManager.GetActiveScene().path).Split(';'); }
    120.         set { EditorPrefs.SetString(cEditorPrefPreviousScenes, String.Join(";", value)); }
    121.     }
    122. }
     
    shaneparsons likes this.
  43. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    @dfraska When I select the menu item it crashes Unity sometimes. Have you noticed this?
     
  44. dfraska

    dfraska

    Joined:
    Mar 1, 2018
    Posts:
    3
    No, I haven't noticed that bug at all. I did make a few more changes to set the scenes to use the same loaded state as before. Note that this new code uses some .NET 4.x features, which is out of experimental as of today since 2018.1.1f1 was released (I'm not sure if it's enabled by default now though).

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4. using System;
    5. using System.Collections.Generic;
    6. using System.Linq;
    7.  
    8. /// <summary>
    9. /// Scene auto loader.
    10. /// </summary>
    11. /// <description>
    12. /// This class adds a File > Scene Autoload menu containing options to select
    13. /// a "master scene" enable it to be auto-loaded when the user presses play
    14. /// in the editor. When enabled, the selected scene will be loaded on play,
    15. /// then the original scene will be reloaded on stop.
    16. ///
    17. /// Based on an idea on this thread:
    18. /// http://forum.unity3d.com/threads/157502-Executing-first-scene-in-build-settings-when-pressing-play-button-in-editor
    19. /// </description>
    20. [InitializeOnLoad]
    21. public static class SceneAutoLoader
    22. {
    23.     // Static constructor binds a playmode-changed callback.
    24.     // [InitializeOnLoad] above makes sure this gets executed.
    25.     static SceneAutoLoader() {
    26.         EditorApplication.playModeStateChanged += OnPlayModeChanged;
    27.     }
    28.  
    29.     // Menu items to select the "master" scene and control whether or not to load it.
    30.     [MenuItem("File/Scene Autoload/Select Master Scene...")]
    31.     private static void SelectMasterScene() {
    32.         string masterScene = EditorUtility.OpenFilePanel("Select Master Scene", Application.dataPath, "unity");
    33.         masterScene = masterScene.Replace(Application.dataPath, "Assets");  //project relative instead of absolute path
    34.         if (!string.IsNullOrEmpty(masterScene)) {
    35.             MasterScene = masterScene;
    36.             LoadMasterOnPlay = true;
    37.         }
    38.     }
    39.  
    40.     [MenuItem("File/Scene Autoload/Load Master On Play", true)]
    41.     private static bool ShowLoadMasterOnPlay() {
    42.         return !LoadMasterOnPlay;
    43.     }
    44.  
    45.     [MenuItem("File/Scene Autoload/Load Master On Play")]
    46.     private static void EnableLoadMasterOnPlay() {
    47.         LoadMasterOnPlay = true;
    48.     }
    49.  
    50.     [MenuItem("File/Scene Autoload/Don't Load Master On Play", true)]
    51.     private static bool ShowDontLoadMasterOnPlay() {
    52.         return LoadMasterOnPlay;
    53.     }
    54.  
    55.     [MenuItem("File/Scene Autoload/Don't Load Master On Play")]
    56.     private static void DisableLoadMasterOnPlay() {
    57.         LoadMasterOnPlay = false;
    58.     }
    59.  
    60.     // Play mode change callback handles the scene load/reload.
    61.     private static void OnPlayModeChanged(PlayModeStateChange state) {
    62.         if (!LoadMasterOnPlay || IsInTestMode) {
    63.             return;
    64.         }
    65.  
    66.         if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode) {
    67.             // User pressed play -- autoload master scene.
    68.             PreviousScenes = BuildPreviousScenesList();
    69.             PreviousScenesLoadedState = BuildPreviousScenesLoadedList();
    70.             if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) {
    71.                 try {
    72.                     EditorSceneManager.OpenScene(MasterScene);
    73.                 } catch {
    74.                     Debug.LogError(string.Format("error: scene not found: {0}", MasterScene));
    75.                     EditorApplication.isPlaying = false;
    76.                 }
    77.             } else {
    78.                 // User cancelled the save operation -- cancel play as well.
    79.                 EditorApplication.isPlaying = false;
    80.             }
    81.         }
    82.  
    83.         // isPlaying check required because cannot OpenScene while playing
    84.         if (!EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode) {
    85.             // User pressed stop -- reload previous scenes.
    86.             foreach (var tuple in Enumerable.Zip(PreviousScenes, PreviousScenesLoadedState, (scene, loadedState) => { return new Tuple<string, bool>(scene, loadedState); })) {
    87.                 try {
    88.                     if (tuple.Item2) {
    89.                         EditorSceneManager.OpenScene(tuple.Item1, OpenSceneMode.Additive);
    90.                     } else {
    91.                         EditorSceneManager.OpenScene(tuple.Item1, OpenSceneMode.AdditiveWithoutLoading);
    92.                     }
    93.                 } catch {
    94.                     Debug.LogError(string.Format("Error: scene not found: {0}", tuple.Item1));
    95.                 }
    96.             }
    97.         }
    98.     }
    99.  
    100.     private static string[] BuildPreviousScenesList() {
    101.         var result = new List<string>();
    102.         for (int i = 0; i < EditorSceneManager.sceneCount; i++) {
    103.             var scene = EditorSceneManager.GetSceneAt(i);
    104.             result.Add(scene.path);
    105.         }
    106.  
    107.         return result.ToArray();
    108.     }
    109.  
    110.     private static bool[] BuildPreviousScenesLoadedList() {
    111.         var result = new List<bool>();
    112.         for (int i = 0; i < EditorSceneManager.sceneCount; i++) {
    113.             var scene = EditorSceneManager.GetSceneAt(i);
    114.             result.Add(scene.isLoaded);
    115.         }
    116.  
    117.         return result.ToArray();
    118.     }
    119.  
    120.     // Properties are remembered as editor preferences.
    121.     private const string cEditorPrefLoadMasterOnPlay = "SceneAutoLoader.LoadMasterOnPlay";
    122.  
    123.     private const string cEditorPrefMasterScene = "SceneAutoLoader.MasterScene";
    124.     private const string cEditorPrefPreviousScenes = "SceneAutoLoader.PreviousScenes";
    125.     private const string cEditorPrefPreviousScenesLoadedState = "SceneAutoLoader.PreviousScenesLoadedState";
    126.  
    127.     private static bool LoadMasterOnPlay {
    128.         get { return EditorPrefs.GetBool(cEditorPrefLoadMasterOnPlay, false); }
    129.         set { EditorPrefs.SetBool(cEditorPrefLoadMasterOnPlay, value); }
    130.     }
    131.  
    132.     private static string MasterScene {
    133.         get { return EditorPrefs.GetString(cEditorPrefMasterScene, "Master.unity"); }
    134.         set { EditorPrefs.SetString(cEditorPrefMasterScene, value); }
    135.     }
    136.  
    137.     private static string[] PreviousScenes {
    138.         get { return EditorPrefs.GetString(cEditorPrefPreviousScenes, String.Join(";", BuildPreviousScenesList())).Split(';'); }
    139.         set { EditorPrefs.SetString(cEditorPrefPreviousScenes, String.Join(";", value)); }
    140.     }
    141.  
    142.     private static bool[] PreviousScenesLoadedState {
    143.         get {
    144.             var strings = EditorPrefs.GetString(cEditorPrefPreviousScenesLoadedState, String.Join(";", BuildPreviousScenesLoadedList())).Split(';');
    145.             List<bool> result = new List<bool>(strings.Length);
    146.             foreach (var s in strings) {
    147.                 result.Add(bool.Parse(s));
    148.             }
    149.             return result.ToArray();
    150.         }
    151.         set { EditorPrefs.SetString(cEditorPrefPreviousScenesLoadedState, String.Join(";", value)); }
    152.     }
    153.  
    154.     public static bool IsInTestMode { get { return EditorSceneManager.GetActiveScene().path.Contains("InitTestScene"); } }
    155. }
     
    PokerDawg likes this.
  45. grfxguru

    grfxguru

    Joined:
    Dec 5, 2017
    Posts:
    6
    Can I just say that this is priceless, thank you so much for saving me from this nightmare!
     
  46. Zekemyapp

    Zekemyapp

    Joined:
    Mar 15, 2015
    Posts:
    2
    You are the real MVP! Thank you
     
  47. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    Unity 2017.1 added the playModeStartScene property, which allows you to easily define a scene to load first, when entering play mode.

    Update: Although this is only an example, I've improved it some to make it more useful as is.

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEditor.SceneManagement;
    3.  
    4. /// <summary>
    5. /// This script ensures the first scene defined in build settings (if any) is always loaded when entering play mode.
    6. /// </summary>
    7. [InitializeOnLoad]
    8. public class AutoPlayModeSceneSetup
    9. {
    10.     static AutoPlayModeSceneSetup()
    11.     {
    12.         // Execute once on Unity editor startup.
    13.         SetStartScene();
    14.  
    15.         // Also execute whenever build settings change.
    16.         EditorBuildSettings.sceneListChanged += SetStartScene;
    17.     }
    18.  
    19.     static void SetStartScene()
    20.     {
    21.         // At least one scene in build settings?
    22.         if (EditorBuildSettings.scenes.Length > 0)
    23.         {
    24.             // Set start scene to first scene in build settings.
    25.             EditorSceneManager.playModeStartScene = AssetDatabase.LoadAssetAtPath<SceneAsset>(EditorBuildSettings.scenes[0].path);
    26.         }
    27.         else
    28.         {
    29.             // Reset start scene.
    30.             EditorSceneManager.playModeStartScene = null;
    31.         }
    32.     }
    33. }
     
    Last edited: Nov 9, 2022
    brainwipe, deivid-01, FlyVC and 11 others like this.
  48. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Holy S***! This actually what I was waiting forever and never thought it was going to happen! This is really a game changer for multiscene setups!

    This is an actually proper way to do it. Main issue with the previous workarounds was that each time play button was pressed, scene setup has to be loaded, then unloaded, and scene 0 has to be loaded again.

    With this it completely bypasses first load and goes straight to the loading master scene directly! (Without firing .Awake() / .Start() and messing around scripts etc);

    Moreover, for me it saves drastic amount of time due to multiscene setup not being loaded / unloaded first.
    I'm so glad that I did searched for this one more time.
     
    IsaiahKelly and Baydogan like this.
  49. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    I have modified this a bit and added a menu tool to Set the current scene as the main start scene in the build settings. One reason it was modified was that if you reordered the build setting items, it does not update to the current scene order. So you be calling the previous scene that was at 0 index instead of the one you just moved to that index. It initially fixes itself after hitting play the second time but thats just time wasted. Now this script looks for the EditorBuildSettings.sceneListChanged callback to update the EditorSceneManager.playModeStartScene immediately so this problem goes away.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4. using System.Collections.Generic;
    5. using System.Linq;
    6.  
    7. //This script was modified from https://forum.unity.com/threads/executing-first-scene-in-build-settings-when-pressing-play-button-in-editor.157502/#post-4152451
    8. [InitializeOnLoad]
    9. public class AutoPlayModeSceneSetup
    10. {
    11.     [MenuItem("Tools/Set As First Scene", false, 0)]
    12.     public static void SetAsFirstScene()
    13.     {
    14.  
    15.         List<EditorBuildSettingsScene> editorBuildSettingsScenes = new List<EditorBuildSettingsScene>(EditorBuildSettings.scenes);
    16.         List<string> scenePaths = editorBuildSettingsScenes.Select(i => i.path).ToList();
    17.  
    18.         //Add the scene to build settings if not already there; place as the first scene
    19.         if (!scenePaths.Contains(EditorSceneManager.GetActiveScene().path))
    20.         {
    21.             editorBuildSettingsScenes.Insert(0, new EditorBuildSettingsScene(EditorSceneManager.GetActiveScene().path, true));
    22.  
    23.         }
    24.         else
    25.         {
    26.  
    27.             //Reference the current scene
    28.             EditorBuildSettingsScene scene = new EditorBuildSettingsScene(EditorSceneManager.GetActiveScene().path, true);
    29.  
    30.             int index = -1;
    31.  
    32.             //Loop and find index from scene; we are doing this way cause IndexOf returns a -1 index for some reason
    33.             for(int i = 0; i < editorBuildSettingsScenes.Count; i++)
    34.             {
    35.                 if(editorBuildSettingsScenes[i].path == scene.path)
    36.                 {
    37.                     index = i;
    38.  
    39.                 }
    40.  
    41.             }
    42.  
    43.             if (index != 0)
    44.             {
    45.                 //Remove from current index
    46.                 editorBuildSettingsScenes.RemoveAt(index);
    47.  
    48.                 //Then place as first scene in build settings
    49.                 editorBuildSettingsScenes.Insert(0, scene);
    50.  
    51.             }
    52.  
    53.         }
    54.  
    55.         //copy arrays back to build setting scenes
    56.         EditorBuildSettings.scenes = editorBuildSettingsScenes.ToArray();
    57.  
    58.     }
    59.  
    60.     static AutoPlayModeSceneSetup()
    61.     {
    62.  
    63.         EditorBuildSettings.sceneListChanged += SceneListChanged;
    64.  
    65.     }
    66.  
    67.     static void SceneListChanged()
    68.     {
    69.  
    70.         // Ensure at least one build scene exist.
    71.         if (EditorBuildSettings.scenes.Length == 0)
    72.         {
    73.             return;
    74.         }
    75.  
    76.         //Reference the first scene
    77.         SceneAsset theScene = AssetDatabase.LoadAssetAtPath<SceneAsset>(EditorBuildSettings.scenes[0].path);
    78.  
    79.         // Set Play Mode scene to first scene defined in build settings.
    80.         EditorSceneManager.playModeStartScene = theScene;
    81.  
    82.     }
    83.  
    84. }
    85.  
    Hopefully someone finds this helpful.

    Thanks,
    jrDev
     
    Freznosis and Nit_Ram like this.
  50. peaj_metric

    peaj_metric

    Joined:
    Sep 15, 2014
    Posts:
    146
    This works great!
    It would be even better if there was a way to quickly reload the open (editor) scenes after loading the start scene.
    Closing all the scenes and then reloading them during playmode takes an additional 30s for me.
    Does anybody have an idea how to keep them in memory?