Init
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class SceneSwitcherToolbar
|
||||
{
|
||||
private static string[] sceneNames = new string[0];
|
||||
private static int selectedIndex = 0;
|
||||
private static string lastActiveScene = "";
|
||||
private static VisualElement toolbarUI;
|
||||
|
||||
private static float positionOffset = 180f;
|
||||
private static float dropdownBoxHeight = 20f;
|
||||
|
||||
private static bool fetchAllScenes
|
||||
{
|
||||
get => EditorPrefs.GetBool("SceneSwitcher_FetchAllScenes", false);
|
||||
set => EditorPrefs.SetBool("SceneSwitcher_FetchAllScenes", value);
|
||||
}
|
||||
|
||||
static SceneSwitcherToolbar()
|
||||
{
|
||||
RefreshSceneList();
|
||||
SelectCurrentScene();
|
||||
|
||||
EditorSceneManager.activeSceneChangedInEditMode += (prev, current) => UpdateSceneSelection();
|
||||
EditorApplication.playModeStateChanged += OnPlayModeChanged;
|
||||
|
||||
EditorApplication.delayCall += AddToolbarUI;
|
||||
}
|
||||
|
||||
static void AddToolbarUI()
|
||||
{
|
||||
var toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
|
||||
if (toolbarType == null) return;
|
||||
|
||||
var toolbars = Resources.FindObjectsOfTypeAll(toolbarType);
|
||||
if (toolbars.Length == 0) return;
|
||||
|
||||
var toolbar = toolbars[0];
|
||||
var rootField = toolbarType.GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (rootField == null) return;
|
||||
|
||||
var root = rootField.GetValue(toolbar) as VisualElement;
|
||||
if (root == null) return;
|
||||
|
||||
var leftContainer = root.Q("ToolbarZoneLeftAlign");
|
||||
if (leftContainer == null) return;
|
||||
|
||||
if (toolbarUI != null)
|
||||
{
|
||||
leftContainer.Remove(toolbarUI);
|
||||
}
|
||||
|
||||
toolbarUI = new IMGUIContainer(OnGUI);
|
||||
toolbarUI.style.marginLeft = positionOffset;
|
||||
|
||||
leftContainer.Add(toolbarUI);
|
||||
}
|
||||
|
||||
static void OnGUI()
|
||||
{
|
||||
CheckAndRefreshScenes();
|
||||
|
||||
if (selectedIndex >= sceneNames.Length)
|
||||
selectedIndex = 0;
|
||||
|
||||
bool isPlaying = EditorApplication.isPlaying;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
// Fetch all scenes toggle button
|
||||
EditorGUI.BeginDisabledGroup(isPlaying);
|
||||
bool newFetchAllScenes = GUILayout.Toggle(fetchAllScenes, "All Scenes", "Button", GUILayout.Height(dropdownBoxHeight));
|
||||
if (newFetchAllScenes != fetchAllScenes)
|
||||
{
|
||||
fetchAllScenes = newFetchAllScenes;
|
||||
RefreshSceneList();
|
||||
SelectCurrentScene();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
// Add Scene button
|
||||
EditorGUI.BeginDisabledGroup(isPlaying || fetchAllScenes);
|
||||
if (GUILayout.Button("Add Scene", GUILayout.Height(dropdownBoxHeight)))
|
||||
{
|
||||
AddCurrentSceneToBuildSettings();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
// Scene dropdown
|
||||
EditorGUI.BeginDisabledGroup(isPlaying);
|
||||
GUIStyle popupStyle = new GUIStyle(EditorStyles.popup)
|
||||
{
|
||||
fixedHeight = dropdownBoxHeight
|
||||
};
|
||||
|
||||
int newIndex = EditorGUILayout.Popup(selectedIndex, sceneNames, popupStyle, GUILayout.Width(150), GUILayout.Height(dropdownBoxHeight));
|
||||
|
||||
if (newIndex != selectedIndex)
|
||||
{
|
||||
selectedIndex = newIndex;
|
||||
LoadScene(sceneNames[selectedIndex]);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void AddCurrentSceneToBuildSettings()
|
||||
{
|
||||
string currentScenePath = EditorSceneManager.GetActiveScene().path;
|
||||
|
||||
if (string.IsNullOrEmpty(currentScenePath))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Scene Not Saved",
|
||||
"Please save the scene before adding it to Build Settings.", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if scene is already in build settings
|
||||
var buildScenes = EditorBuildSettings.scenes.ToList();
|
||||
bool sceneExists = buildScenes.Any(s => s.path == currentScenePath);
|
||||
|
||||
if (sceneExists)
|
||||
{
|
||||
// Enable the scene if it was disabled
|
||||
var existingScene = buildScenes.Find(s => s.path == currentScenePath);
|
||||
if (!existingScene.enabled)
|
||||
{
|
||||
existingScene.enabled = true;
|
||||
EditorBuildSettings.scenes = buildScenes.ToArray();
|
||||
Debug.Log($"<color=green>Scene '{Path.GetFileNameWithoutExtension(currentScenePath)}' enabled in Build Settings.</color>");
|
||||
RefreshSceneList();
|
||||
SelectCurrentScene();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"Scene '{Path.GetFileNameWithoutExtension(currentScenePath)}' is already in Build Settings.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add new scene to build settings
|
||||
buildScenes.Add(new EditorBuildSettingsScene(currentScenePath, true));
|
||||
EditorBuildSettings.scenes = buildScenes.ToArray();
|
||||
|
||||
Debug.Log($"<color=green>Scene '{Path.GetFileNameWithoutExtension(currentScenePath)}' added to Build Settings.</color>");
|
||||
|
||||
RefreshSceneList();
|
||||
SelectCurrentScene();
|
||||
}
|
||||
}
|
||||
|
||||
static void RefreshSceneList()
|
||||
{
|
||||
if (fetchAllScenes)
|
||||
{
|
||||
sceneNames = Directory.GetFiles("Assets", "*.unity", SearchOption.AllDirectories)
|
||||
.Select(path => Path.GetFileNameWithoutExtension(path))
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
sceneNames = EditorBuildSettings.scenes
|
||||
.Where(scene => scene.enabled)
|
||||
.Select(scene => Path.GetFileNameWithoutExtension(scene.path))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckAndRefreshScenes()
|
||||
{
|
||||
string[] currentScenes;
|
||||
if (fetchAllScenes)
|
||||
{
|
||||
currentScenes = Directory.GetFiles("Assets", "*.unity", SearchOption.AllDirectories)
|
||||
.Select(path => Path.GetFileNameWithoutExtension(path))
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentScenes = EditorBuildSettings.scenes
|
||||
.Where(scene => scene.enabled)
|
||||
.Select(scene => Path.GetFileNameWithoutExtension(scene.path))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (!currentScenes.SequenceEqual(sceneNames))
|
||||
{
|
||||
sceneNames = currentScenes;
|
||||
SelectCurrentScene();
|
||||
}
|
||||
}
|
||||
|
||||
static void SelectCurrentScene()
|
||||
{
|
||||
string currentScene = Path.GetFileNameWithoutExtension(EditorSceneManager.GetActiveScene().path);
|
||||
int index = System.Array.IndexOf(sceneNames, currentScene);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
selectedIndex = index;
|
||||
lastActiveScene = currentScene;
|
||||
}
|
||||
else
|
||||
{
|
||||
string notInBuildName = currentScene + " (not in build index)";
|
||||
sceneNames = new[] { notInBuildName }.Concat(sceneNames).ToArray();
|
||||
selectedIndex = 0;
|
||||
lastActiveScene = currentScene;
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateSceneSelection()
|
||||
{
|
||||
string currentScene = Path.GetFileNameWithoutExtension(EditorSceneManager.GetActiveScene().path);
|
||||
if (currentScene != lastActiveScene)
|
||||
{
|
||||
lastActiveScene = currentScene;
|
||||
sceneNames = sceneNames.Where(name => !name.EndsWith(" (not in build index)")).ToArray();
|
||||
SelectCurrentScene();
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadScene(string sceneName)
|
||||
{
|
||||
string scenePath;
|
||||
|
||||
if (fetchAllScenes)
|
||||
{
|
||||
scenePath = Directory.GetFiles("Assets", "*.unity", SearchOption.AllDirectories)
|
||||
.FirstOrDefault(path => Path.GetFileNameWithoutExtension(path) == sceneName);
|
||||
}
|
||||
else
|
||||
{
|
||||
scenePath = EditorBuildSettings.scenes
|
||||
.FirstOrDefault(scene => scene.enabled && scene.path.Contains(sceneName))?.path;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(scenePath))
|
||||
{
|
||||
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
|
||||
{
|
||||
EditorSceneManager.OpenScene(scenePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Scene not found: " + sceneName);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnPlayModeChanged(PlayModeStateChange state)
|
||||
{
|
||||
if (state == PlayModeStateChange.EnteredPlayMode || state == PlayModeStateChange.ExitingPlayMode)
|
||||
{
|
||||
EditorApplication.delayCall += () => AddToolbarUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09ae5cf30ab3ca54f92f91841e5f2c04
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 313355
|
||||
packageName: Scene Switcher Pro
|
||||
packageVersion: 1.0.0
|
||||
assetPath: Assets/SceneSwitcherPro/Editor/SceneSwitcherToolbar.cs
|
||||
uploadId: 758164
|
||||
Reference in New Issue
Block a user