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. Dismiss Notice

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

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

  1. Freznosis

    Freznosis

    Joined:
    Jul 16, 2014
    Posts:
    294
    In case anyone is using this script like I am, you need to change static AutoPlayModeSceneSetup() from this

    Code (CSharp):
    1.     static AutoPlayModeSceneSetup()
    2.     {
    3. EditorBuildSettings.sceneListChanged += SceneListChanged;
    4.     }
    to this

    Code (CSharp):
    1.     static AutoPlayModeSceneSetup()
    2.     {
    3.         //Call scenelistchanged at start up.
    4.         SceneListChanged();
    5.        
    6.         EditorBuildSettings.sceneListChanged += SceneListChanged;
    7.     }
    So that the startup scene is set even without the scenelist updating. I wanted to get the behavior no matter if I just started Unity or just changed the scene list. This change makes it work perfectly!
     
  2. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    714
    Works like a charm... I endorse yoyo for president of The National Badass Association.
     
  3. ledshok

    ledshok

    Joined:
    Oct 28, 2012
    Posts:
    28
    Agreed, the script is excellent. Saves me a ton of time.

    Thanks for sharing it!
     
  4. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    wiki version works great. It's similar to one I used on the asset store that was free 2-3 years ago that has disappeared.
     
  5. AlternativeShit

    AlternativeShit

    Joined:
    Feb 17, 2021
    Posts:
    18
    Sorry for bump but I just wanted to say that I'm so glad I found this solution, it's absolutely amazing!
     
  6. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    Thanks @AlternativeShit! Nice name too ;).

    Always touching when someone takes the time to thank you for something, so I greatly appreciate it. But I am Just happy I could help people discover this great feature because it is super useful.
     
    AlternativeShit likes this.
  7. Laur3nt1u

    Laur3nt1u

    Joined:
    Apr 30, 2014
    Posts:
    23
    It's so much better when you have multiple projects

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using UnityEditor.SceneManagement;
    4. /// <summary>
    5. /// First Scene Auto Loader
    6. /// </summary>
    7. /// <description>
    8. /// Based on an idea on this thread:
    9. /// http://forum.unity3d.com/threads/157502-Executing-first-scene-in-build-settings-when-pressing-play-button-in-editor
    10. /// </description>
    11. [InitializeOnLoad]
    12. public static class FirstSceneAutoLoader {
    13.  
    14.     private const string NAME = "• Custom/Load First Scene";
    15.  
    16.     static bool isEnabled {
    17.         get {
    18.            return EditorPrefs.GetBool(NAME, false);
    19.         }
    20.         set {
    21.             EditorPrefs.SetBool(NAME, value);
    22.             SceneListChanged();
    23.         }
    24.     }
    25.  
    26.     [MenuItem(NAME, false, 0)]
    27.     static void LoadFirstScene() {
    28.         isEnabled = !isEnabled;
    29.     }
    30.  
    31.     [MenuItem(NAME, true, 0)]
    32.     static bool ValidateLoadFirstScene() {
    33.         Menu.SetChecked(NAME, isEnabled);
    34.         return true;
    35.     }
    36.  
    37.     static FirstSceneAutoLoader() {
    38.         SceneListChanged();
    39.  
    40.         EditorBuildSettings.sceneListChanged += SceneListChanged;
    41.     }
    42.  
    43.     static void SceneListChanged() {
    44.         if(!isEnabled) {
    45.             EditorSceneManager.playModeStartScene = default;
    46.             return;
    47.         }
    48.         //Ensure at least one build scene exist.
    49.         if(EditorBuildSettings.scenes.Length == 0) {
    50.             Debug.Log("No Scenes in Build Settings");
    51.             isEnabled = false;
    52.             return;
    53.         }
    54.         //Reference the first scene
    55.         SceneAsset theScene = AssetDatabase.LoadAssetAtPath<SceneAsset>(EditorBuildSettings.scenes[0].path);
    56.         // Set Play Mode scene to first scene defined in build settings.
    57.         EditorSceneManager.playModeStartScene = theScene;
    58.     }
    59. }
    This is my version so you can quickly enable/disable
     
    Last edited: Mar 30, 2021
    deivid-01, _geo__ and IsaiahKelly like this.
  8. AlternativeShit

    AlternativeShit

    Joined:
    Feb 17, 2021
    Posts:
    18
    Sorry to bump this again, but I ran into some issue with your bit of code (I think...) :)

    Changing EditorSceneManager.playModeStartScene seems to be definitive, because even if I remove my script entirely, it still load my scene 0 again, and not my current scene.

    I don't know how to set it back to default.
    Does someone know ?
     
  9. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    You need to set playModeStartScene to "default", otherwise previously set will persist.

    Also, its better to just expose option from which to load or just wrap into define, instead of removing script completely.
     
    AlternativeShit likes this.
  10. AlternativeShit

    AlternativeShit

    Joined:
    Feb 17, 2021
    Posts:
    18
    I don't know what you mean by "wrap into define". Can you show me an example ?

    Thanks for your answer, setting it to "default" did the trick (I didn't know I just could say playModeStartScene = default)
     
  11. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    I'm using scripting defines to toggle between, e.g.
    Code (CSharp):
    1. #if START_FROM_SPECIFIC
    2. EditorSceneManager.playModeStartScene = theScene;
    3. #else
    4. EditorSceneManager.playModeStartScene = default;
    5. #endif
    Then define it in Project Settings -> Player -> Scripting Define symbols as START_FROM_SPECIFIC;

    Alternatively, its possible to expose it as MenuItem toggle, and save from which to load by using EditorPrefs.

    Something like (pseudocode):
    Code (CSharp):
    1. #if UNITY_EDITOR
    2.    public static class StartupSceneExt {
    3.       private const string MenuName = "Tools/Start From Scene";
    4.  
    5.       // 1. Perform default initialization / set playmode scene via constructor (or InitializeOnLoad),
    6.       // but load path from EditorPrefs instead or use default if not set
    7.       // 2. Setup initial toggle state (via Menu.SetChecked)
    8.  
    9.       // Then define menu item
    10.       [MenuItem(MenuName)]
    11.       private static void ToggleScenes() {
    12.          bool isActive = !EditorPrefs.GetBool(*key*);
    13.          EditorPrefs.SetBool(*key*, isActive);
    14.  
    15.          // 3. Modify from which scene to start, save scene path to Editor Prefs.
    16.  
    17.          // 4. This changes menu toggle state
    18.          Menu.SetChecked(MenuName, isActive);
    19.       }
    20.    }
    21. #endif
     
    Last edited: Mar 29, 2021
    ledshok and AlternativeShit like this.
  12. AlternativeShit

    AlternativeShit

    Joined:
    Feb 17, 2021
    Posts:
    18
    Okay thanks, it makes a bit more sense ! That's a lot of stuff I didn't know I could do :D
    Didn't understand everything, but I'm glad I have your example as referance to figure it out.
     
    xVergilx likes this.
  13. MUGIK

    MUGIK

    Joined:
    Jul 2, 2015
    Posts:
    452
    crafTDev and ledshok like this.
  14. Jorhoto

    Jorhoto

    Joined:
    May 7, 2019
    Posts:
    99
    Hi all, can you make it to work with playmode tests?
    What I found is that when you start your test in playmode, it jumps to your default scene previously set. It seems also that once playModeStartScene is set, it can't be reset until an editor restart.
     
    MikePhill likes this.
  15. MUGIK

    MUGIK

    Joined:
    Jul 2, 2015
    Posts:
    452
    You can set it to null :)

    I think the best solution would be to place an additional button near playmode button that will trigger entering playmode from main scene.
    Somewhere here:
    upload_2021-11-18_12-59-12.png
     
    brainwipe likes this.
  16. Jorhoto

    Jorhoto

    Joined:
    May 7, 2019
    Posts:
    99
    It doesn't seem to work either.

    Another issue with multiscene and playmode tests is that, in case you run your playmode tests with more than a scene loaded, once you return you find you get only 1 scene loaded back and the rest were removed.
     
    MikePhill likes this.
  17. pezezzle

    pezezzle

    Joined:
    Nov 17, 2019
    Posts:
    11
    i use this, put it in Editor Folder:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4.  
    5. [InitializeOnLoad]
    6. public class DefaultSceneLoader : EditorWindow
    7. {
    8.  
    9.     private const string defaultScenePath = "Assets/Scenes/Preload.unity";
    10.  
    11.     static DefaultSceneLoader()
    12.     {
    13.         EditorApplication.playModeStateChanged += LoadDefaultScene;
    14.     }
    15.  
    16.     static void LoadDefaultScene(PlayModeStateChange state)
    17.     {
    18.         if (state == PlayModeStateChange.ExitingEditMode)
    19.         {
    20.             if (EditorSceneManager.GetActiveScene().path != defaultScenePath)
    21.             {
    22.              
    23.                 PlayerPrefs.SetString("dsl_lastPath", EditorSceneManager.GetActiveScene().path);
    24.                 PlayerPrefs.Save();
    25.  
    26.                 EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();
    27.  
    28.                 EditorApplication.delayCall += () =>
    29.                 {
    30.                     EditorSceneManager.OpenScene(defaultScenePath);
    31.                     EditorApplication.isPlaying = true;
    32.                 };
    33.  
    34.                 EditorApplication.isPlaying = false;
    35.             }
    36.         }
    37.  
    38.         if (state == PlayModeStateChange.EnteredEditMode)
    39.         {
    40.             if (PlayerPrefs.HasKey("dsl_lastPath"))
    41.             {
    42.                 EditorSceneManager.OpenScene(PlayerPrefs.GetString("dsl_lastPath"));
    43.             }
    44.         }
    45.     }
    46. }
    47.