Created
August 30, 2024 11:21
-
-
Save badscotsman/903ad9b0a0003fb986b461bb65db1841 to your computer and use it in GitHub Desktop.
A simple Scene selector Overlay
This file contains hidden or 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 UnityEngine; | |
| namespace SceneSelector | |
| { | |
| [CreateAssetMenu(fileName = "SceneSelectorConfig", menuName = "Editor/Scene Selector Configuration", order = 1)] | |
| public class SceneSelectorConfigSO : ScriptableObject | |
| { | |
| public string SceneFilter = "t:Scene"; | |
| public string[] SceneNames; | |
| public string[] PreferredScenePaths; | |
| } | |
| } |
This file contains hidden or 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.IO; | |
| using UnityEditor; | |
| using UnityEditor.Overlays; | |
| using UnityEditor.SceneManagement; | |
| using UnityEditor.Toolbars; | |
| using UnityEngine; | |
| using UnityEngine.SceneManagement; | |
| namespace SceneSelector | |
| { | |
| [Overlay(typeof(SceneView), "Scene Selector")] | |
| [Icon(ICON_PATH)] | |
| public class SceneSelectorOverlay : ToolbarOverlay | |
| { | |
| public static SceneSelectorConfigSO Config; | |
| // The path to the configuration asset must be updated per project - it must exist. | |
| public const string CONFIG_PATH = "Assets/Editor/SceneSelectorOverlay/Settings/SceneSelectorConfig.asset"; | |
| // The path to the icon for the overlay must be updated per project - it must exist. | |
| public const string ICON_PATH = "Assets/Editor/SceneSelectorOverlay/SceneSelectorIcon.png"; | |
| private SceneSelectorOverlay() : base(SceneDropdownToggle.ID) | |
| { | |
| Config = AssetDatabase.LoadAssetAtPath<SceneSelectorConfigSO>(CONFIG_PATH); | |
| if (Config == null) | |
| { | |
| Debug.LogWarning("Scene Selector Overlay configuration is not set up!"); | |
| } | |
| } | |
| [EditorToolbarElement(ID, typeof(SceneView))] | |
| private class SceneDropdownToggle : EditorToolbarDropdownToggle, IAccessContainerWindow | |
| { | |
| public const string ID = "SceneSelectorOverlay/SceneDropdownToggle"; | |
| public EditorWindow containerWindow { get; set; } | |
| private SceneDropdownToggle() | |
| { | |
| text = "Scenes"; | |
| tooltip = "Select a Scene to Load"; | |
| icon = AssetDatabase.LoadAssetAtPath<Texture2D>(ICON_PATH); | |
| dropdownClicked += ShowSceneMenu; | |
| } | |
| private void ShowSceneMenu() | |
| { | |
| var menu = new GenericMenu(); | |
| var currentScene = SceneManager.GetActiveScene(); | |
| if (Config != null && Config.SceneNames.Length > 0) | |
| { | |
| foreach (var sceneName in Config.SceneNames) | |
| { | |
| if (Config.PreferredScenePaths != null && Config.PreferredScenePaths.Length > 0) | |
| { | |
| PopulateMenuWithScenePaths(menu, sceneName, currentScene); | |
| } | |
| else | |
| { | |
| PopulateMenuWithSceneName(menu, sceneName, currentScene); | |
| } | |
| } | |
| } | |
| else if (Config != null) | |
| { | |
| PopulateMenuWithFilter(menu, Config.SceneFilter, currentScene); | |
| } | |
| menu.ShowAsContext(); | |
| } | |
| private void PopulateMenuWithFilter(GenericMenu menu, string filter, Scene currentScene) | |
| { | |
| string[] sceneGuids = AssetDatabase.FindAssets(filter); | |
| foreach (var guid in sceneGuids) | |
| { | |
| string path = AssetDatabase.GUIDToAssetPath(guid); | |
| var name = Path.GetFileNameWithoutExtension(path); | |
| menu.AddItem( | |
| new GUIContent(name), | |
| string.Compare(currentScene.name, name) == 0, | |
| () => OpenScene(currentScene, path)); | |
| } | |
| } | |
| private void PopulateMenuWithScenePaths(GenericMenu menu, string sceneName, Scene currentScene) | |
| { | |
| foreach (var possiblePath in Config.PreferredScenePaths) | |
| { | |
| string[] guids = AssetDatabase.FindAssets($"t:Scene {sceneName}", new[] { possiblePath }); | |
| AddItems(guids, sceneName, currentScene, menu); | |
| } | |
| } | |
| private void PopulateMenuWithSceneName(GenericMenu menu, string sceneName, Scene currentScene) | |
| { | |
| string[] guids = AssetDatabase.FindAssets($"t:Scene {sceneName}"); | |
| AddItems(guids, sceneName, currentScene, menu); | |
| } | |
| private void AddItems(string[] guids, string sceneName, Scene currentScene, GenericMenu menu) | |
| { | |
| foreach (var guid in guids) | |
| { | |
| string path = AssetDatabase.GUIDToAssetPath(guid); | |
| if (Path.GetFileNameWithoutExtension(path).Equals(sceneName, System.StringComparison.OrdinalIgnoreCase)) | |
| { | |
| menu.AddItem( | |
| new GUIContent(sceneName), | |
| string.Compare(currentScene.name, sceneName, System.StringComparison.OrdinalIgnoreCase) == 0, | |
| () => OpenScene(currentScene, path)); | |
| } | |
| } | |
| } | |
| } | |
| private static void OpenScene(Scene currentScene, string path) | |
| { | |
| if (!currentScene.isDirty) | |
| { | |
| EditorSceneManager.OpenScene(path); | |
| return; | |
| } | |
| if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) | |
| { | |
| EditorSceneManager.OpenScene(path); | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Icon image to use for 'SceneSelectorIcon.png' :)
