Fast Scene Switching in the Unity Editor

One of the many powerful features of Unity is the ability to write extensions for the editor. As I worked on Voyager: Grand Tour, I found myself doing a number of repetitive tasks – not terribly time-consuming individually, but frustrating enough in aggregate to get me curious about optimizing my workflow with software. Still, I put it off, figuring I didn’t have time to divert toward extraneous development to save a few seconds here and there.

Well, a few months ago, a friend of mine by the name of Zach Aikman gave a talk on Unity Editor extensions at the local Unity user group meetup. His detailed overview provided more than enough information to get me started, and the first thing I did when I got home was to whip up a solution to a problem that, while small, had nagged me frequently while developing Voyager: quickly switching between scenes.

In my game, I split my content and menus up into a lot of scenes that I frequently had to switch between, which in the default Unity editor meant a lot of pointlessly scrolling around in the project view. This simple editor window grabs a list of scenes from the Build Settings and presents them as buttons for fast switching. It’s dead simple, but it genuinely saves me time and frustration every day, and I’m happy to share it with anyone who’s interested!

// --------------------------------
// <copyright file="SceneSwitchWindow.cs" company="Rumor Games">
//     Copyright (C) Rumor Games, LLC.  All rights reserved.
// </copyright>
// --------------------------------

using System.IO;
using UnityEditor;
using UnityEngine;

/// <summary>
/// SceneSwitchWindow class.
/// </summary>
public class SceneSwitchWindow : EditorWindow
{
    /// <summary>
    /// Tracks scroll position.
    /// </summary>
    private Vector2 scrollPos;

    /// <summary>
    /// Initialize window state.
    /// </summary>
	[MenuItem("Tools/Scene Switch Window")]
    internal static void Init()
    {
        // EditorWindow.GetWindow() will return the open instance of the specified window or create a new
        // instance if it can't find one. The second parameter is a flag for creating the window as a
        // Utility window; Utility windows cannot be docked like the Scene and Game view windows.
        var window = (SceneSwitchWindow)GetWindow(typeof(SceneSwitchWindow), false, "Scene Switch");
        window.position = new Rect(window.position.xMin + 100f, window.position.yMin + 100f, 200f, 400f);
    }

    /// <summary>
    /// Called on GUI events.
    /// </summary>
    internal void OnGUI()
    {
        EditorGUILayout.BeginVertical();
        this.scrollPos = EditorGUILayout.BeginScrollView(this.scrollPos, false, false);

        GUILayout.Label("Scenes In Build", EditorStyles.boldLabel);
        for (var i = 0; i < EditorBuildSettings.scenes.Length; i++)
        {
            var scene = EditorBuildSettings.scenes[i];
            if (scene.enabled)
            {
                var sceneName = Path.GetFileNameWithoutExtension(scene.path);
                var pressed = GUILayout.Button(i + ": " + sceneName, new GUIStyle(GUI.skin.GetStyle("Button")) { alignment = TextAnchor.MiddleLeft });
                if (pressed)
                {
                    if (EditorApplication.SaveCurrentSceneIfUserWantsTo())
                    {
                        EditorApplication.OpenScene(scene.path);
                    }
                }
            }
        }

        EditorGUILayout.EndScrollView();
        EditorGUILayout.EndVertical();
    }
}

Now also available on the Unify Community Wiki.