-
-
Save BenVella/cce177aee3025819a0aef729df30573f to your computer and use it in GitHub Desktop.
SceneAutoLoader with additive loading
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; | |
namespace Editor | |
{ | |
/// <summary> | |
/// Scene auto loader. | |
/// </summary> | |
/// <description> | |
/// This class adds a File > Scene Autoload menu containing options to select | |
/// a "master scene" enable it to be auto-loaded when the user presses play | |
/// in the editor. When enabled, the selected scene will be loaded on play, | |
/// then the original scene will be reloaded on stop. | |
/// | |
/// Based on an idea on this thread: | |
/// http://forum.unity3d.com/threads/157502-Executing-first-scene-in-build-settings-when-pressing-play-button-in-editor | |
/// </description> | |
[InitializeOnLoad] | |
internal static class SceneAutoLoader | |
{ | |
// Static constructor binds a playmode-changed callback. | |
// [InitializeOnLoad] above makes sure this gets executed. | |
static SceneAutoLoader() | |
{ | |
EditorApplication.playModeStateChanged += OnPlayModeChanged; | |
} | |
// Menu items to select the "master" scene and control whether or not to load it. | |
[MenuItem("File/Scene Autoload/Select Master Scene...")] | |
private static void SelectMasterScene() | |
{ | |
string masterScene = EditorUtility.OpenFilePanel("Select Master Scene", Application.dataPath, "unity"); | |
if (!string.IsNullOrEmpty(masterScene)) | |
{ | |
MasterScene = masterScene; | |
LoadMasterOnPlay = true; | |
} | |
} | |
[MenuItem("File/Scene Autoload/----------------------")] | |
private static void Separator1() | |
{} | |
[MenuItem("File/Scene Autoload/Load Master On Play", true)] | |
private static bool ShowLoadMasterOnPlay() | |
{ | |
return !LoadMasterOnPlay; | |
} | |
[MenuItem("File/Scene Autoload/Load Master On Play")] | |
private static void EnableLoadMasterOnPlay() | |
{ | |
LoadMasterOnPlay = true; | |
} | |
[MenuItem("File/Scene Autoload/Don't Load Master On Play", true)] | |
private static bool ShowDontLoadMasterOnPlay() | |
{ | |
return LoadMasterOnPlay; | |
} | |
[MenuItem("File/Scene Autoload/Don't Load Master On Play")] | |
private static void DisableLoadMasterOnPlay() | |
{ | |
LoadMasterOnPlay = false; | |
} | |
[MenuItem("File/Scene Autoload/-------------------------")] | |
private static void Separator2() | |
{ } | |
[MenuItem("File/Scene Autoload/Load current scene additively", true)] | |
private static bool ShowLoadAdditiveCurrentScene() | |
{ | |
return !LoadAdditiveCurrentScene; | |
} | |
[MenuItem("File/Scene Autoload/Load current scene additively")] | |
private static void EnableLoadAdditiveCurrentScene() | |
{ | |
LoadAdditiveCurrentScene = true; | |
} | |
[MenuItem("File/Scene Autoload/Don't Load current scene additively", true)] | |
private static bool ShowDontLoadAdditiveCurrentScene() | |
{ | |
return LoadAdditiveCurrentScene; | |
} | |
[MenuItem("File/Scene Autoload/Don't Load current scene additively")] | |
private static void DisableLoadAdditiveCurrentScene() | |
{ | |
LoadAdditiveCurrentScene = false; | |
} | |
// Play mode change callback handles the scene load/reload. | |
private static void OnPlayModeChanged(PlayModeStateChange playModeStateChange) | |
{ | |
if (!LoadMasterOnPlay) | |
{ | |
return; | |
} | |
switch (playModeStateChange) | |
{ | |
case PlayModeStateChange.ExitingEditMode: | |
BeginningPlay(); | |
break; | |
case PlayModeStateChange.EnteredEditMode: | |
StoppingPlay(); | |
break; | |
case PlayModeStateChange.EnteredPlayMode: | |
case PlayModeStateChange.ExitingPlayMode: | |
default: | |
return; | |
} | |
} | |
private static void StoppingPlay() | |
{ | |
try | |
{ | |
EditorSceneManager.OpenScene(PreviousScene); | |
} | |
catch (ArgumentException argEx) | |
{ | |
Debug.LogError($"Failed to open {PreviousScene}. Error: {argEx.Message}\n{argEx.StackTrace}"); | |
} | |
} | |
private static void BeginningPlay() | |
{ | |
PreviousScene = SceneManager.GetActiveScene().path; | |
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) | |
{ | |
try | |
{ | |
EditorSceneManager.OpenScene(MasterScene); | |
} | |
catch (ArgumentException argEx) | |
{ | |
Debug.LogError($"Failed to open {MasterScene}. Error: {argEx.Message}\n{argEx.StackTrace}"); | |
EditorApplication.isPlaying = false; | |
} | |
} | |
else | |
{ | |
// User cancelled the save operation -- cancel play as well. | |
EditorApplication.isPlaying = false; | |
} | |
if (LoadAdditiveCurrentScene) | |
{ | |
var sceneName = PreviousScene.Split('/', '.'); | |
SceneManager.LoadScene(sceneName[^2]); | |
} | |
} | |
// Properties are remembered as editor preferences. | |
private const string EditorPrefLoadMasterOnPlay = "SceneAutoLoader.LoadMasterOnPlay"; | |
private const string EditorPrefMasterScene = "SceneAutoLoader.MasterScene"; | |
private const string EditorPrefPreviousScene = "SceneAutoLoader.PreviousScene"; | |
private const string EditorPrefLoadAdditiveCurrentScene = "SceneAutoLoader.LoadAdditiveCurrentScene"; | |
private static bool LoadMasterOnPlay | |
{ | |
get => EditorPrefs.GetBool(EditorPrefLoadMasterOnPlay, false); | |
set => EditorPrefs.SetBool(EditorPrefLoadMasterOnPlay, value); | |
} | |
private static string MasterScene | |
{ | |
get => EditorPrefs.GetString(EditorPrefMasterScene, "Master.unity"); | |
set => EditorPrefs.SetString(EditorPrefMasterScene, value); | |
} | |
private static string PreviousScene | |
{ | |
get => EditorPrefs.GetString(EditorPrefPreviousScene, SceneManager.GetActiveScene().name); | |
set => EditorPrefs.SetString(EditorPrefPreviousScene, value); | |
} | |
private static bool LoadAdditiveCurrentScene | |
{ | |
get => EditorPrefs.GetBool(EditorPrefLoadAdditiveCurrentScene, false); | |
set => EditorPrefs.SetBool(EditorPrefLoadAdditiveCurrentScene, value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment