Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
21
Question by Fattie · Apr 19, 2013 at 10:25 AM · editor scripting

Editor script to make Play button always jump to a start scene

Dear Editor Script Genius friends ..

So you have say 10 scenes in a project. In any real project it "has to" begin on a particular scene, your scene 0, "GamePrep" which loads stuff to make the game work.

When you're working on the game in the editor. You might be working on some other scene, say scene 4.

Every single time you hit play in the editor, in reality you FIRST have to click to scene zero, and then hit play.

Would it be possible, using Editor Script magic, to fix this Common Problem ?

So, when you click or keystroke "Play", it changes you to scene 0, and only then "Play"s.


BTW Here's a full simple working solution based on everyone's amazing work below!

 // IN YOUR EDITOR FOLDER, have SimpleEditorUtils.cs.
 // paste in this text.
 // to play, HIT COMMAND-ZERO rather than command-P
 // (the zero key, is near the P key, so it's easy to remember)
 // simply insert the actual name of your opening scene
 // "__preEverythingScene" on the second last line of code below.
 
 using UnityEditor;
 using UnityEngine;
 using System.Collections;
 
 [InitializeOnLoad]
 public static class SimpleEditorUtils
     {
     // click command-0 to go to the prelaunch scene and then play
     
     [MenuItem("Edit/Play-Unplay, But From Prelaunch Scene %0")]
     public static void PlayFromPrelaunchScene()
         {
         if ( EditorApplication.isPlaying == true )
             {
             EditorApplication.isPlaying = false;
             return;
             }
         EditorApplication.SaveCurrentSceneIfUserWantsTo();
         EditorApplication.OpenScene(
                     "Assets/stuff/Scenes/__preEverythingScene.unity");
         EditorApplication.isPlaying = true;
         }
     }




Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Arcanor · Mar 25, 2017 at 02:21 PM 0
Share

The API was different back then, so now in Unity 5.5 it's possible to use generic code that will trigger scene 0 from your build settings, and not need to hard code the string path to your base scene.

 #if UNITY_EDITOR
             UnityEditor.Scene$$anonymous$$anagement.EditorScene$$anonymous$$anager.SaveCurrent$$anonymous$$odifiedScenesIfUserWantsTo();
             UnityEditor.Scene$$anonymous$$anagement.EditorScene$$anonymous$$anager.OpenScene(EditorBuildSettings.scenes[0].path);
             EditorApplication.isPlaying = true;
 #endif
 

avatar image nirnirle · Jun 26, 2017 at 08:59 AM 0
Share

Great Solution! The only thing that is missing is using the output of SaveCurrent$$anonymous$$odifiedScenesIfUserWantsTo If there are changes to the scene the user can cancel the scene change.

So you should do something like: bool isOk = EditorScene$$anonymous$$anager.SaveCurrent$$anonymous$$odifiedScenesIfUserWantsTo(); if (isOk) EditorScene$$anonymous$$anager.OpenScene("Assets/" + sceneName + ".unity");

avatar image JasonsFreeTime · Jan 10, 2019 at 11:55 PM 0
Share

Best answer: Go here and get this: http://wiki.unity3d.com/index.php/SceneAutoLoader

12 Replies

· Add your reply
  • Sort: 
avatar image
17
Best Answer

Answer by Loius · Apr 29, 2013 at 04:02 PM

Menu item with a shortcut!

 using UnityEditor;
 using UnityEngine;
 using System.IO;
 using System.Linq;
 using System.Collections;
 
 [ExecuteInEditMode]
 public class PlayFromScene : EditorWindow {
     [SerializeField] string lastScene="";
     [SerializeField] int targetScene = 0;
     [SerializeField] string waitScene = null;
     [SerializeField] bool hasPlayed = false;
 
     [MenuItem("Edit/Play From Scene %0")]
     public static void Run() {
         EditorWindow.GetWindow<PlayFromScene>();
     }
     static string[] sceneNames;
     static EditorBuildSettingsScene[] scenes;
 
     void OnEnable() {
         scenes = EditorBuildSettings.scenes;
         sceneNames = scenes.Select(x=>AsSpacedCamelCase(Path.GetFileNameWithoutExtension(x.path))).ToArray();
     }
 
     void Update() {
         if ( !EditorApplication.isPlaying ) {
             if ( null==waitScene && !string.IsNullOrEmpty(lastScene) ) {
                 EditorApplication.OpenScene(lastScene);
                 lastScene = null;
             }
         }
     }
 
     void OnGUI() {
         if ( EditorApplication.isPlaying ) {
             if ( EditorApplication.currentScene == waitScene ) {
                 waitScene = null;
             }
             return;
         }
 
         if ( EditorApplication.currentScene == waitScene ) {
             EditorApplication.isPlaying = true;
         }
         if ( null == sceneNames ) return;
         targetScene = EditorGUILayout.Popup(targetScene,sceneNames);
         if(GUILayout.Button("Play")) {
             lastScene = EditorApplication.currentScene;
             waitScene = scenes[targetScene].path;
             EditorApplication.SaveCurrentSceneIfUserWantsTo();
             EditorApplication.OpenScene(waitScene);
         }
     }
 
     public string AsSpacedCamelCase(string text) {
         System.Text.StringBuilder sb = new System.Text.StringBuilder(text.Length*2);
         sb.Append(char.ToUpper(text[0]));
         for(int i=1; i<text.Length;i++) {
             if ( char.IsUpper(text[i]) && text[i-1] != ' ' )
                 sb.Append(' ');
             sb.Append (text[i]);
         }
         return sb.ToString();
     }
 }

give Tonyli a bump up too if this works for ya, i totally stole his words


[Editor's note.. and here's the original "super-elegant" solution. I have found it very useful:]

 // class doesn't matter, add to anything in the Editor folder
 // for any beginners reading, this is c#
 
 [MenuItem("Edit/Play-Stop, But From Prelaunch Scene %0")]
 public static void PlayFromPrelaunchScene()
     {
      if ( EditorApplication.isPlaying == true )
         {
         EditorApplication.isPlaying = false;
         return;
         }
     
     EditorApplication.SaveCurrentSceneIfUserWantsTo();
     EditorApplication.OpenScene("Assets/whatever/YourPrepScene.unity");
     EditorApplication.isPlaying = true;
     }
Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · Oct 07, 2013 at 09:24 AM 0
Share

Sorry for the extreme delay in ticking. This is awesome, thanks! You've performed your "Help a non-Editor programmer" kind act for the day :)

Curiosities:

(1) is there an easy way in Editor to open an scene by index number? (as one can just use LoadLevel with an index, when running.) Or is it a $$anonymous$$nown Nuisance in Editor program$$anonymous$$g?

(2) Here's a challenge - in that code, how would you know "when the Play run has finished" .. one could then revert to the level that the developer was working on before hitting Apple-Zero.

I could not find either of these by searching

Thank you again !!!

avatar image Loius · Oct 17, 2013 at 09:46 PM 0
Share

Retaliatory delay! (or... just busy x_x)

There's this one by Yoyo on the wiki: http://wiki.unity3d.com/index.php/SceneAutoLoader

Then there's this one I just put together because it works the way I WANT IT TO GAGAGAGAHAGHGH AND I A$$anonymous$$ ALWAYS RIGHT (it's slightly different and appeals to my usage needs, maybe it's good for learnin or whatever)

$$anonymous$$ine will only play from scenes that are in the build settings, because I need control over some of my designers (e_e). Yoyo's uses a file dialog to pick a scene, could be worth combining them.

(code added to answer)

that'll be tree-fiddy

avatar image chillersanim · Oct 17, 2013 at 10:31 PM 1
Share

Please be aware that when building a game, the compiler has problems with inEditorCode when referencing the "using UnityEditor;"
You can simply avoid this by just wraping the whole code in between of the folowing compile code:

 #if UNITY_EDITOR
 //Code
 #EndIf

That should do the trick, the code won't be compiled when you build the game.

Greetings
Chillersanim

avatar image Loius · Oct 18, 2013 at 07:19 AM 0
Share

Well, it's an EditorWindow, it has to go in the Editor folder. But yes.

avatar image Fattie · Oct 18, 2013 at 04:04 PM 0
Share

Thanks for that - thanks. I did re-include the original "super short, super simple" solution.

I have found it incredibly useful. Everyone I show it to adopts use of it!

Show more comments
avatar image
12

Answer by YinXiaozhou · Sep 26, 2016 at 04:08 AM

After 5.2, Unity introduced RuntimeInitializeLoadType.BeforeSceneLoad. So we can get a perfect version of this. What does the perfect mean?

  • Hook into the play button. So you don't need use the menu item.

  • Automatically use the currently scene changes in runtime, you don't even need to save them.

  • After exit play mode, scene go back to previously editing scene. And the all the unsaved changes still there.

So here's the code,

 public static class PlayFromTheFirstScene
 {      
     const string playFromFirstMenuStr = "Edit/Always Start From Scene 0 &p";
 
     static bool playFromFirstScene
     {
         get{return EditorPrefs.HasKey(playFromFirstMenuStr) && EditorPrefs.GetBool(playFromFirstMenuStr);}
         set{EditorPrefs.SetBool(playFromFirstMenuStr, value);}
     }
 
     [MenuItem(playFromFirstMenuStr, false, 150)]
     static void PlayFromFirstSceneCheckMenu() 
     {
         playFromFirstScene = !playFromFirstScene;
         Menu.SetChecked(playFromFirstMenuStr, playFromFirstScene);
 
         ShowNotifyOrLog(playFromFirstScene ? "Play from scene 0" : "Play from current scene");
     }
 
     // The menu won't be gray out, we use this validate method for update check state
     [MenuItem(playFromFirstMenuStr, true)]
     static bool PlayFromFirstSceneCheckMenuValidate()
     {
         Menu.SetChecked(playFromFirstMenuStr, playFromFirstScene);
         return true;
     }
 
     // This method is called before any Awake. It's the perfect callback for this feature
     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] 
     static void LoadFirstSceneAtGameBegins()
     {
         if(!playFromFirstScene)
             return;
 
         if(EditorBuildSettings.scenes.Length  == 0)
         {
             Debug.LogWarning("The scene build list is empty. Can't play from first scene.");
             return;
         }
 
         foreach(GameObject go in Object.FindObjectsOfType<GameObject>())
             go.SetActive(false);
         
         SceneManager.LoadScene(0);
     }
 
     static void ShowNotifyOrLog(string msg)
     {
         if(Resources.FindObjectsOfTypeAll<SceneView>().Length > 0)
             EditorWindow.GetWindow<SceneView>().ShowNotification(new GUIContent(msg));
         else
             Debug.Log(msg); // When there's no scene view opened, we just print a log
     }
 }

Enjoy! Oh, also, there's some other useful tricks like how to make a checkable menu item correctly, or how to show a compile error like message in the scene view. Check them out in the code if you interested.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AndBje · Feb 04, 2017 at 12:09 PM 0
Share

Thank you very much! Excellent solution with modern code, thanks for sharing.

(Had to change line 35 from Count() to Length - I am using Unity 5.5).

avatar image YinXiaozhou AndBje · Jul 05, 2018 at 03:33 AM 0
Share

Thanks for the feedback. Script updated.

avatar image
7

Answer by TonyLi · Apr 19, 2013 at 02:53 PM

How about this?

In scene 0, create a game object called "Scene 0 Object" and attach this script:

 public class DontDestroyOnLoad : MonoBehaviour {
     void Start() {
         DontDestroyOnLoad(this.GameObject);
     }
 }


In your other scenes, create a game object called "Play Scene 0" and attach this script:

 public class PlayScene0 : MonoBehaviour {
     void Start() {
         if (Application.isEditor && (GameObject.Find("Scene 0 Object") == null)) {
             Application.LoadLevel(0);
         }
     }
 }

You can make this a prefab and just add the prefab to every scene.

This way you can continue using your regular play button. If you really want to run from scene 4 instead of auto-loading scene 0 on play, just disable the "Play Scene 0" object.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TonyLi · Apr 19, 2013 at 05:26 PM 3
Share

Your best bet is to create a custom EditorWindow with a Play button that would run this:

 EditorApplication.SaveCurrentSceneIfUserWantsTo();
 EditorApplication.OpenScene(scene0path);
 EditorApplication.isPlaying = true;

where scene0path is the path to your scene 0.

http://docs.unity3d.com/Documentation/ScriptReference/EditorApplication.html

avatar image rrertgwe · Oct 16, 2017 at 09:01 PM 0
Share

Safest solution.

avatar image DawidNorasDev · Jul 05, 2018 at 08:35 AM 0
Share

This is a very ugly solution. Not needed objects in the scenes, just to make some editor utility functionality.

avatar image
4
Wiki

Answer by Jamora · Oct 07, 2013 at 02:13 PM

My approach would be to directly hook into the user pressing the play button with the following code:

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 
 [InitializeOnLoad]
 public static class LoadSceneOnPressingPlay{
     
     [SerializeField]
     public static string oldScene;
     
     static void LoadSceneOnPressingPlay(){
         EditorApplication.playmodeStateChanged += StateChange;
     }
     
     static void StateChange(){
         if(EditorApplication.isPlaying){
             EditorApplication.playmodeStateChanged -= StateChange;
             if(!EditorApplication.isPlayingOrWillChangePlaymode){
                 //We're in playmode, just about to change playmode to Editor
                 Debug.Log("Loading original level");
                 EditorApplication.OpenScene(oldScene);
             }else{
                 //We're in playmode, right after having pressed Play
                 oldScene = EditorApplication.currentScene;
                 Debug.Log("Loading first level");
                 Application.LoadLevel(0);
             }
         }
     }
 }


For the record, the alternative to LoadLevel in the Editor is

 EditorApplication.OpenScene(EditorBuildSettings.scenes[levelIndex].path);
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · Oct 07, 2013 at 03:01 PM 0
Share

" ~ Holy ~ "

avatar image Jamora · Oct 07, 2013 at 04:57 PM 0
Share

This script - or rather, Application.LoadLevel - won't work if the scene in which Play is pressed is not in the build setting scene list. I have no idea why.

avatar image meat5000 ♦ · May 14, 2016 at 04:08 PM 0
Share

"directly hook into the user pressing the play button"

Sorry had a good LOL at that. Gave me thoughts of Pinhead.

avatar image abeldantas · Apr 28, 2017 at 06:04 PM 1
Share

The constructor shouldn't return void

try:

     static LoadSceneOnPressingPlay()
     {
         EditorApplication.playmodeStateChanged += StateChange;
     }
avatar image
2

Answer by Xevoius · Apr 15, 2014 at 07:14 AM

I just went through setting up Fattie's Grid system with the Scene Auto Loader by User_Yoyo in a little video I put together.

Note: This movie shows how to rig it so when you press play, the pre-game scene gets loaded and then the scene you are working on gets automatically loaded after that.

https://www.youtube.com/watch?v=lWmk2QXy4wU

I also put a download link to the package in the movie details.

Let me know if you find any mistakes.

Share and enjoy.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image JamesAMD · Dec 26, 2015 at 05:10 AM 1
Share

Thanks! This is very helpful and I really appreciate it :)

avatar image Fattie JamesAMD · Dec 26, 2015 at 02:05 PM 0
Share

nice demo by XEVOius

  • 1
  • 2
  • 3
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

35 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

how to print selected game object in editor to console? 1 Answer

Programatically create Assembly Definition 0 Answers

MenuItem Glitch: Editor Script MenuItem Calling Wrong Option From Unity Help Menu 0 Answers

GetAssetPreview returns null 0 Answers

Accessing Sprite mesh from editor script 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges