Last active
June 4, 2019 12:39
-
-
Save shane-harper/9d3703241a50c465bead31b7f8595397 to your computer and use it in GitHub Desktop.
Auto opens a scene on Unity Editor play
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEditor; | |
using UnityEditor.SceneManagement; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
[InitializeOnLoad] | |
internal static class SceneAutoLoader | |
{ | |
private const string MenuFolder = "Edit/Scene Auto Load/"; | |
private const string ToggleMenuItem = MenuFolder + "Enabled"; | |
private const string SelectSceneMenuItem = MenuFolder + "Select Scene..."; | |
private const string PrefLoadMasterOnPlay = "SceneAutoLoader.Enabled"; | |
private const string PrefMasterScene = "SceneAutoLoader.MasterScene"; | |
private const string PrefPreviousScene = "SceneAutoLoader.PreviousScene"; | |
static SceneAutoLoader() | |
{ | |
// Subscribe to event if enabled | |
if (Enabled) EditorApplication.playModeStateChanged += OnPlayModeChanged; | |
// TODO this can sometimes throw an error on editor opening (harmless but ugly) | |
Menu.SetChecked(ToggleMenuItem, Enabled); | |
} | |
/// <summary> | |
/// Returns true if the tool is currently enabled | |
/// </summary> | |
private static bool Enabled | |
{ | |
get { return PlayerPrefs.GetInt(PrefLoadMasterOnPlay, 0) == 1; } | |
set { PlayerPrefs.SetInt(PrefLoadMasterOnPlay, value ? 1 : 0); } | |
} | |
/// <summary> | |
/// The currently set master scene | |
/// </summary> | |
private static string MasterScene | |
{ | |
get { return PlayerPrefs.GetString(PrefMasterScene, DefaultMasterScene); } | |
set { PlayerPrefs.SetString(PrefMasterScene, value); } | |
} | |
/// <summary> | |
/// Last scene the user was on before they pressed play | |
/// </summary> | |
private static string PreviousScene | |
{ | |
get { return PlayerPrefs.GetString(PrefPreviousScene, SceneManager.GetActiveScene().path); } | |
set { PlayerPrefs.SetString(PrefPreviousScene, value); } | |
} | |
/// <summary> | |
/// Get path to default master scene. Used when no master scene is set | |
/// </summary> | |
private static string DefaultMasterScene | |
{ | |
get { return EditorBuildSettings.scenes.Length > 0 ? EditorBuildSettings.scenes[0].path : null; } | |
} | |
[MenuItem(SelectSceneMenuItem)] | |
public static void SelectMasterScene() | |
{ | |
var masterScene = EditorUtility.OpenFilePanel("Select Master Scene", Application.dataPath, "unity"); | |
masterScene = masterScene.Replace(Application.dataPath, "Assets"); | |
if (string.IsNullOrEmpty(masterScene)) return; | |
MasterScene = masterScene; | |
// Enable if disabled | |
if (!Enabled) Toggle(); | |
} | |
[MenuItem(ToggleMenuItem)] | |
public static void Toggle() | |
{ | |
Enabled = !Enabled; | |
Menu.SetChecked(ToggleMenuItem, Enabled); | |
if (Enabled) EditorApplication.playModeStateChanged += OnPlayModeChanged; | |
else EditorApplication.playModeStateChanged -= OnPlayModeChanged; | |
} | |
[MenuItem(ToggleMenuItem, true)] | |
private static bool ToggleCheck() | |
{ | |
Menu.SetChecked(ToggleMenuItem, Enabled); | |
return true; | |
} | |
private static void OnPlayModeChanged(PlayModeStateChange state) | |
{ | |
switch (state) | |
{ | |
case PlayModeStateChange.ExitingEditMode: | |
{ | |
OnPlay(); | |
break; | |
} | |
case PlayModeStateChange.EnteredEditMode: | |
{ | |
OnStop(); | |
break; | |
} | |
} | |
} | |
private static void OnPlay() | |
{ | |
// If no master scene is set, don't do anything | |
if (string.IsNullOrEmpty(MasterScene)) return; | |
// Cache previous scene path, ignore if already on the master scene | |
PreviousScene = SceneManager.GetActiveScene().path; | |
if (PreviousScene == MasterScene) | |
{ | |
PreviousScene = null; | |
return; | |
} | |
// Show save dialog | |
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) | |
// Open master scene | |
try | |
{ | |
EditorSceneManager.OpenScene(MasterScene); | |
} | |
catch (Exception) | |
{ | |
EditorApplication.isPlaying = false; | |
// Disable if currently enabled as current master scene selection does not exist | |
if (Enabled) Toggle(); | |
} | |
else | |
// Cancel playing if user chooses to cancel the save dialog | |
EditorApplication.isPlaying = false; | |
} | |
private static void OnStop() | |
{ | |
// Don't attempt to load previous scene if it's not set | |
if (string.IsNullOrEmpty(PreviousScene)) return; | |
try | |
{ | |
// Open previous scene | |
EditorSceneManager.OpenScene(PreviousScene); | |
} | |
catch (Exception) | |
{ | |
// Previous scene doesn't exist anymore | |
Debug.LogErrorFormat("Scene Auto Loader: Couldn't find previous scene to load.\n{0}", PreviousScene); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment