#if UNITY_EDITOR #nullable enable using System.Collections; using System.Collections.Generic; using CCG.Shared.DependencyInjection.Unity; using UnityEngine; using ILogger = Microsoft.Extensions.Logging.ILogger; using UnityEditor; using UnityEditor.SceneManagement; namespace CCG.Bigfoot.TestScripts { /// <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] public static class SceneAutoLoader { public static bool shiftPressed = false; // Properties are remembered as editor preferences. private static string cEditorPrefLoadMasterOnPlay = Application.productName + ".SceneAutoLoader.LoadMasterOnPlay"; private static string cEditorPrefMasterScene = Application.productName + ".SceneAutoLoader.MasterScene"; private static string cEditorPrefPreviousScene = Application.productName + ".SceneAutoLoader.PreviousScene"; private static bool IsLoadMasterOnPlay { get { return EditorPrefs.GetBool(cEditorPrefLoadMasterOnPlay, false); } set { EditorPrefs.SetBool(cEditorPrefLoadMasterOnPlay, value); } } private static string MasterSceneSetting { get { return EditorPrefs.GetString(cEditorPrefMasterScene, "Master.unity"); } set { EditorPrefs.SetString(cEditorPrefMasterScene, value); } } private static string LastSceneSetting { get { return EditorPrefs.GetString(cEditorPrefPreviousScene, EditorSceneManager.GetActiveScene().path); } set { EditorPrefs.SetString(cEditorPrefPreviousScene, value); } } // Static constructor binds a playmode-changed callback. // [InitializeOnLoad] above makes sure this gets executed. static SceneAutoLoader() { EditorApplication.playModeStateChanged += EditorApplication_playModeStateChanged; //SceneView.onSceneGUIDelegate += view => // { // var e = Event.current; // if (e != null && e.type == EventType.KeyDown && e.keyCode != KeyCode.None && e.keyCode == KeyCode.LeftShift) // { // shiftPressed = true; // } // else // if (e != null && e.type == EventType.KeyUp && e.keyCode != KeyCode.None && e.keyCode == KeyCode.LeftShift) // { // shiftPressed = false; // } // }; } // Menu items to select the "master" scene and control whether or not to load it. [MenuItem("File/Scene Autoloader/Select Master Scene...")] static void SelectMasterScene() { string masterScene = EditorUtility.OpenFilePanel("Select Master Scene", Application.dataPath, "unity"); masterScene = masterScene.Replace(Application.dataPath, "Assets"); //project relative instead of absolute path if (!string.IsNullOrEmpty(masterScene)) { MasterSceneSetting = masterScene; IsLoadMasterOnPlay = true; } } [MenuItem("File/Scene Autoloader/Load Master On Play", true)] private static bool ShowLoadMasterOnPlay() { return !IsLoadMasterOnPlay; } [MenuItem("File/Scene Autoloader/Load Master On Play")] private static void EnableLoadMasterOnPlay() { IsLoadMasterOnPlay = true; } [MenuItem("File/Scene Autoloader/Don't Load Master On Play", true)] private static bool ShowDontLoadMasterOnPlay() { return IsLoadMasterOnPlay; } [MenuItem("File/Scene Autoloader/Don't Load Master On Play")] private static void DisableLoadMasterOnPlay() { IsLoadMasterOnPlay = false; } // Play mode change callback handles the scene load/reload. private static void EditorApplication_playModeStateChanged(PlayModeStateChange obj) { switch (obj) { case PlayModeStateChange.ExitingEditMode: { LoadMasterScene(); break; } case PlayModeStateChange.EnteredEditMode: { LoadPreviousScene(); break; } } } private static void LoadMasterScene() { if (!IsLoadMasterOnPlay) { LastSceneSetting = string.Empty; return; } if (shiftPressed) { LastSceneSetting = string.Empty; Debug.Log($"SceneAutoLoader - Shift held down so using current scene instead of master scene [MasterScene]"); return; } try { string currentScene = EditorSceneManager.GetActiveScene().path; EditorSceneManager.OpenScene(MasterSceneSetting); LastSceneSetting = currentScene; } catch (System.Exception ex) { Debug.LogError($"SceneAutoLoader exception: " + ex.Message); Debug.LogError($"SceneAutoLoader: continuing without master scene"); } } private static void LoadPreviousScene() { if (!IsLoadMasterOnPlay) { LastSceneSetting = string.Empty; return; } // User pressed stop -- reload previous scene. try { EditorSceneManager.OpenScene(LastSceneSetting); } catch (System.Exception ex) { Debug.LogError($"SceneAutoLoader exception: " + ex.Message); Debug.LogError($"SceneAutoLoader: Warning: scene not found: [{LastSceneSetting}]"); } } } } #endif