diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4acaaed..79af572 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file.
+## [2.0.0] - 2025-12-06
+- Navigation tools upgraded to use the new `MainToolbarElement` API
+
+
## [1.11.4] - 2025-09-21
### Fixed
diff --git a/Editor/Toolbar/AbstractToolbarDrawer.cs b/Editor/Toolbar/AbstractToolbarDrawer.cs
index 3f5aefc..66110a9 100644
--- a/Editor/Toolbar/AbstractToolbarDrawer.cs
+++ b/Editor/Toolbar/AbstractToolbarDrawer.cs
@@ -1,7 +1,13 @@
using UnityEngine;
+#if UNITY_6000_3_OR_NEWER
+using System;
+#endif
namespace Module.NavigationTool.Editor.Toolbar
{
+#if UNITY_6000_3_OR_NEWER
+ [Obsolete("Unity has added a new API for adding elements to the main toolbar. Check: MainToolbarElement.")]
+#endif
public abstract class AbstractToolbarDrawer
{
public abstract bool Visible { get; }
@@ -9,18 +15,22 @@ namespace Module.NavigationTool.Editor.Toolbar
public abstract EToolbarPlacement Placement { get; }
public abstract int Priority { get; }
- private Rect rect;
protected Styles styles;
-
+
+#if !UNITY_6000_3_OR_NEWER
+ private Rect rect;
+
public void Setup(Rect rect)
{
this.rect = rect;
}
+#endif
public virtual void Update()
{
}
+#if !UNITY_6000_3_OR_NEWER
public void OnGUI()
{
if (styles == null)
@@ -32,6 +42,7 @@ namespace Module.NavigationTool.Editor.Toolbar
Draw(rect);
GUI.enabled = true;
}
+#endif
protected abstract void Draw(Rect rect);
public abstract float CalculateWidth();
diff --git a/Editor/Toolbar/MainToolbarElements.meta b/Editor/Toolbar/MainToolbarElements.meta
new file mode 100644
index 0000000..9823427
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: b007385b54fa43af8050fe2edd5b0174
+timeCreated: 1765022906
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/Handlers.meta b/Editor/Toolbar/MainToolbarElements/Handlers.meta
new file mode 100644
index 0000000..8e371e4
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/Handlers.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 2bb70affaf1b42d9b59779683dbbb62d
+timeCreated: 1765023522
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerPostProcess.cs b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerPostProcess.cs
new file mode 100644
index 0000000..f5bb081
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerPostProcess.cs
@@ -0,0 +1,22 @@
+#if UNITY_6000_3_OR_NEWER
+using System.Linq;
+using UnityEditor;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ internal sealed class MainToolbarScenePickerPostProcess : AssetPostprocessor
+ {
+ private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
+ {
+ if (HasChange(deletedAssets) || HasChange(movedAssets) || HasChange(importedAssets))
+ MainToolbarScenePickerElement.Refresh();
+ }
+
+ private static bool HasChange(string[] assets)
+ {
+ return assets.Any(s => s.EndsWith(".unity")) ||
+ assets.Any(s => s.EndsWith("EditorBuildSettings.asset"));
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerPostProcess.cs.meta b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerPostProcess.cs.meta
new file mode 100644
index 0000000..e022c8a
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerPostProcess.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 1a8274c0b09c4ccf99d08c1e6db45331
+timeCreated: 1765023528
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerStateChanged.cs b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerStateChanged.cs
new file mode 100644
index 0000000..5ddcfe8
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerStateChanged.cs
@@ -0,0 +1,64 @@
+#if UNITY_6000_3_OR_NEWER
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using UnityEngine.SceneManagement;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ [InitializeOnLoad]
+ internal static class MainToolbarScenePickerStateChanged
+ {
+ static MainToolbarScenePickerStateChanged()
+ {
+ EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
+ SceneManager.activeSceneChanged += OnActiveSceneChanged;
+ SceneManager.sceneLoaded += OnSceneLoaded;
+ SceneManager.sceneUnloaded += OnSceneUnloaded;
+ EditorSceneManager.newSceneCreated += OnNewSceneCreated;
+ EditorSceneManager.activeSceneChangedInEditMode += OnActiveSceneChangedInEditMode;
+ EditorSceneManager.sceneOpened += OnSceneOpened;
+ EditorSceneManager.sceneClosed += OnSceneClosed;
+ }
+
+ private static void OnPlayModeStateChanged(PlayModeStateChange state)
+ {
+ MainToolbarScenePickerElement.Refresh();
+ }
+
+ private static void OnActiveSceneChanged(Scene current, Scene next)
+ {
+ MainToolbarScenePickerElement.Refresh();
+ }
+
+ private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
+ {
+ MainToolbarScenePickerElement.Refresh();
+ }
+
+ private static void OnSceneUnloaded(Scene arg0)
+ {
+ MainToolbarScenePickerElement.Refresh();
+ }
+
+ private static void OnActiveSceneChangedInEditMode(Scene from, Scene to)
+ {
+ MainToolbarScenePickerElement.Refresh();
+ }
+
+ private static void OnNewSceneCreated(Scene scene, NewSceneSetup setup, NewSceneMode mode)
+ {
+ MainToolbarScenePickerElement.Refresh();
+ }
+
+ private static void OnSceneOpened(Scene scene, OpenSceneMode mode)
+ {
+ MainToolbarScenePickerElement.Refresh();
+ }
+
+ private static void OnSceneClosed(Scene scene)
+ {
+ MainToolbarScenePickerElement.Refresh();
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerStateChanged.cs.meta b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerStateChanged.cs.meta
new file mode 100644
index 0000000..ba4d86e
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarScenePickerStateChanged.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 0c9bd16d885949239ac6b9f7ce1825ec
+timeCreated: 1765023528
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarUIStateChanged.cs b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarUIStateChanged.cs
new file mode 100644
index 0000000..51c8add
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarUIStateChanged.cs
@@ -0,0 +1,47 @@
+#if UNITY_6000_3_OR_NEWER
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using UnityEngine.SceneManagement;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ [InitializeOnLoad]
+ internal static class MainToolbarUIStateChanged
+ {
+ static MainToolbarUIStateChanged()
+ {
+ EditorSceneManager.sceneSaved += OnSceneSaved;
+ EditorSceneManager.sceneOpened += OnSceneOpened;
+ EditorSceneManager.sceneClosed += OnSceneClosed;
+
+ PrefabStage.prefabStageOpened += OnPrefabStageOpened;
+ PrefabStage.prefabStageClosing += OnPrefabStageClosing;
+ }
+
+ private static void OnSceneSaved(Scene scene)
+ {
+ MainToolbarUIElement.Refresh();
+ }
+
+ private static void OnSceneOpened(Scene scene, OpenSceneMode mode)
+ {
+ MainToolbarUIElement.Refresh();
+ }
+
+ private static void OnSceneClosed(Scene scene)
+ {
+ MainToolbarUIElement.Refresh();
+ }
+
+ private static void OnPrefabStageOpened(PrefabStage stage)
+ {
+ MainToolbarUIElement.Refresh();
+ }
+
+ private static void OnPrefabStageClosing(PrefabStage stage)
+ {
+ MainToolbarUIElement.Refresh();
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarUIStateChanged.cs.meta b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarUIStateChanged.cs.meta
new file mode 100644
index 0000000..e70442a
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/Handlers/MainToolbarUIStateChanged.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 21f843e3d88741ef985041ddb1fa986d
+timeCreated: 1765024267
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarBuildElement.cs b/Editor/Toolbar/MainToolbarElements/MainToolbarBuildElement.cs
new file mode 100644
index 0000000..714b39e
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarBuildElement.cs
@@ -0,0 +1,103 @@
+#if UNITY_6000_3_OR_NEWER
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using UnityEditor;
+using UnityEditor.Toolbars;
+using UnityEngine;
+using UnityEngine.Scripting;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ internal static class MainToolbarBuildElement
+ {
+ [Preserve]
+ [MainToolbarElement("Toolbar/Build", ussName = "", defaultDockIndex = 0, defaultDockPosition = MainToolbarDockPosition.Middle, menuPriority = 500)]
+ public static IEnumerable Draw()
+ {
+ var target = EditorUserBuildSettings.activeBuildTarget;
+ var group = BuildPipeline.GetBuildTargetGroup(target);
+
+ return new List(2)
+ {
+ new MainToolbarDropdown(new MainToolbarContent("Build", "Select build or build & run options"), OnBuildDropdownOpened),
+ new MainToolbarDropdown(GetButtonContent(group), OnBuildTargetDropdownOpened)
+ };
+ }
+
+ private static void OnBuildDropdownOpened(Rect rect)
+ {
+ var menu = new GenericMenu();
+ menu.AddItem(new GUIContent("Build", "Build project with current EditorBuildSettings and target platform"), false, () => Build(false));
+ menu.AddItem(new GUIContent("Build & Run", "Build & Run project with current EditorBuildSettings and target platform"), false, () => Build(false));
+ menu.DropDown(rect);
+ }
+
+ private static void OnBuildTargetDropdownOpened(Rect rect)
+ {
+ var menu = new GenericMenu();
+ var type = typeof(BuildTarget);
+ var values = Enum.GetValues(type);
+
+ for (var i = 0; i < values.Length; i++)
+ {
+ var target = (BuildTarget)values.GetValue(i);
+ var group = BuildPipeline.GetBuildTargetGroup(target);
+
+ if (target < 0 || !BuildPipeline.IsBuildTargetSupported(group, target))
+ continue;
+ if (!IsValid(type, target))
+ continue;
+
+ menu.AddItem(new GUIContent(ObjectNames.NicifyVariableName(target.ToString())), false, () => SetBuildTargetTo(group, target));
+ }
+
+ menu.DropDown(rect);
+ }
+
+ private static void SetBuildTargetTo(BuildTargetGroup group, BuildTarget target)
+ {
+ if (EditorUserBuildSettings.SwitchActiveBuildTarget(group, target))
+ MainToolbar.Refresh("Toolbar/Build Targets");
+ }
+
+ private static bool IsValid(Type type, BuildTarget target)
+ {
+ var members = type.GetMember(target.ToString(), BindingFlags.Public | BindingFlags.Static);
+
+ if (members.Length == 0)
+ return false;
+
+ for (var j = 0; j < members.Length; j++)
+ {
+ if (members[j].GetCustomAttribute() == null)
+ return true;
+ }
+
+ return false;
+ }
+
+ private static GUIContent GetButtonContent(BuildTargetGroup group)
+ {
+ var name = $"BuildSettings.{group}.Small";
+
+ if (group == BuildTargetGroup.WSA)
+ name = "BuildSettings.Metro.Small";
+
+ var iconContent = EditorGUIUtility.IconContent(name);
+ var content = new GUIContent(iconContent.image, "Select target platform for build");
+ return content;
+ }
+
+ private static void Build(bool withAutorun)
+ {
+ var options = BuildPlayerWindow.DefaultBuildMethods.GetBuildPlayerOptions(new BuildPlayerOptions());
+
+ if (withAutorun)
+ options.options |= BuildOptions.AutoRunPlayer;
+
+ BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options);
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarBuildElement.cs.meta b/Editor/Toolbar/MainToolbarElements/MainToolbarBuildElement.cs.meta
new file mode 100644
index 0000000..0fd5821
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarBuildElement.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 7c4b306cf95144139c540aa7b6c0a156
+timeCreated: 1765022920
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarPlayerPrefsElement.cs b/Editor/Toolbar/MainToolbarElements/MainToolbarPlayerPrefsElement.cs
new file mode 100644
index 0000000..b39d8e9
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarPlayerPrefsElement.cs
@@ -0,0 +1,28 @@
+#if UNITY_6000_3_OR_NEWER
+using UnityEditor;
+using UnityEditor.Toolbars;
+using UnityEngine;
+using UnityEngine.Scripting;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ internal static class MainToolbarPlayerPrefsElement
+ {
+ [Preserve]
+ [MainToolbarElement("Toolbar/Player Prefs Delete", ussName = "", defaultDockIndex = 100, defaultDockPosition = MainToolbarDockPosition.Middle, menuPriority = 1500)]
+ public static MainToolbarElement Draw()
+ {
+ var icon = EditorGUIUtility.IconContent("d_CacheServerDisconnected").image as Texture2D;
+ var content = new MainToolbarContent(icon, "Deletes all PlayerPrefs entries");
+ return new MainToolbarButton(content, () =>
+ {
+ if (!EditorUtility.DisplayDialog("Delete PlayerPrefs", "Are you sure you want to delete all PlayerPrefs data?", "Yes", "No"))
+ return;
+
+ PlayerPrefs.DeleteAll();
+ PlayerPrefs.Save();
+ });
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarPlayerPrefsElement.cs.meta b/Editor/Toolbar/MainToolbarElements/MainToolbarPlayerPrefsElement.cs.meta
new file mode 100644
index 0000000..2dc8f6b
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarPlayerPrefsElement.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a926471f33c04f7fb75a32f84c6c9d1b
+timeCreated: 1765023278
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSaveElement.cs b/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSaveElement.cs
new file mode 100644
index 0000000..c1eb0f7
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSaveElement.cs
@@ -0,0 +1,21 @@
+#if UNITY_6000_3_OR_NEWER
+using UnityEditor;
+using UnityEditor.Toolbars;
+using UnityEngine;
+using UnityEngine.Scripting;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ internal static class MainToolbarProjectSaveElement
+ {
+ [Preserve]
+ [MainToolbarElement("Toolbar/Project/Save", ussName = "", defaultDockIndex = 100, defaultDockPosition = MainToolbarDockPosition.Middle, menuPriority = 1500)]
+ public static MainToolbarElement Draw()
+ {
+ var icon = EditorGUIUtility.IconContent("Project").image as Texture2D;
+ var content = new MainToolbarContent(icon, "Saves all changed assets");
+ return new MainToolbarButton(content, AssetDatabase.SaveAssets);
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSaveElement.cs.meta b/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSaveElement.cs.meta
new file mode 100644
index 0000000..7c4c112
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSaveElement.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 8383da48c39b4300b74e9c1791c32a8a
+timeCreated: 1765024530
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSettingsElement.cs b/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSettingsElement.cs
new file mode 100644
index 0000000..02cdff9
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSettingsElement.cs
@@ -0,0 +1,29 @@
+#if UNITY_6000_3_OR_NEWER
+using UnityEditor;
+using UnityEditor.Toolbars;
+using UnityEngine;
+using UnityEngine.Scripting;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ internal static class MainToolbarProjectSettingsElement
+ {
+ [Preserve]
+ [MainToolbarElement("Toolbar/Project/Open Settings", ussName = "", defaultDockIndex = 100, defaultDockPosition = MainToolbarDockPosition.Middle, menuPriority = 1500)]
+ public static MainToolbarElement Draw()
+ {
+ var icon = EditorGUIUtility.IconContent("Settings").image as Texture2D;
+ var content = new MainToolbarContent(icon, "Opens Preferences/Project Settings");
+ return new MainToolbarDropdown(content, OnDropdownOpen);
+ }
+
+ private static void OnDropdownOpen(Rect rect)
+ {
+ var menu = new GenericMenu();
+ menu.AddItem(new GUIContent("Preferences"), false, () => SettingsService.OpenUserPreferences("Module/Toolbar"));
+ menu.AddItem(new GUIContent("Project Settings"), false, () => SettingsService.OpenProjectSettings("Module/Toolbar"));
+ menu.DropDown(rect);
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSettingsElement.cs.meta b/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSettingsElement.cs.meta
new file mode 100644
index 0000000..b412347
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarProjectSettingsElement.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 5ebe021aec8e4dc58d5eb863695e3485
+timeCreated: 1765024477
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarScenePickerElement.cs b/Editor/Toolbar/MainToolbarElements/MainToolbarScenePickerElement.cs
new file mode 100644
index 0000000..33d3ddf
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarScenePickerElement.cs
@@ -0,0 +1,187 @@
+#if UNITY_6000_3_OR_NEWER
+using System;
+using System.Collections.Generic;
+using System.Text;
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using UnityEditor.Toolbars;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+using UnityEngine.Scripting;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ internal static class MainToolbarScenePickerElement
+ {
+ private static readonly ScenePickerList SceneList = new();
+
+ [Preserve]
+ [MainToolbarElement("Toolbar/Scene", ussName = "", defaultDockIndex = 100, defaultDockPosition = MainToolbarDockPosition.Middle, menuPriority = 1500)]
+ public static IEnumerable Draw()
+ {
+ return new List(3)
+ {
+ CreateDropdownSceneList(),
+ CreateToggleSceneLoad(),
+ CreateButtonAddNewScene()
+ };
+ }
+
+ private static MainToolbarDropdown CreateDropdownSceneList()
+ {
+ SceneList.Refresh();
+ var content = new MainToolbarContent(GetSceneLabel());
+ return new MainToolbarDropdown(content, rect =>
+ {
+ var menu = new GenericMenu();
+
+ for (var i = 0; i < SceneList.labels.Length; i++)
+ {
+ var sceneIndex = i;
+ menu.AddItem(SceneList.labels[i], SceneList.selected.Contains(i), () => SelectScene(sceneIndex));
+ }
+
+ menu.DropDown(rect);
+ });
+ }
+
+ private static MainToolbarToggle CreateToggleSceneLoad()
+ {
+ var isScenePickerSetAsAdditive = ToolbarScenePickerSettings.IsScenePickerSetAsAdditive;
+ var content = isScenePickerSetAsAdditive
+ ? new MainToolbarContent("A", "Additive scene loading (toogle to Single)")
+ : new MainToolbarContent("S", "Single scene loading (toggle to Additive)");
+
+ return new MainToolbarToggle(content, isScenePickerSetAsAdditive, result =>
+ {
+ ToolbarScenePickerSettings.IsScenePickerSetAsAdditive = result;
+ MainToolbar.Refresh("Toolbar/Scene");
+ });
+ }
+
+ private static MainToolbarButton CreateButtonAddNewScene()
+ {
+ var icon = EditorGUIUtility.IconContent("d_CreateAddNew").image as Texture2D;
+ var content = new MainToolbarContent(icon, "Create a new scene");
+ return new MainToolbarButton(content, () =>
+ {
+ try
+ {
+ var selection = EditorUtility.DisplayDialogComplex("Create new scene", "How do you want to add the scene?", "Single", "Additive", "Cancel");
+
+ if (selection == 2)
+ return;
+
+ var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, selection == 0 ? NewSceneMode.Single : NewSceneMode.Additive);
+
+ if (EditorUtility.DisplayDialog("Create new scene", "Save scene to disk?", "Yes", "No"))
+ EditorSceneManager.SaveScene(scene);
+ }
+ catch (Exception e)
+ {
+ EditorUtility.DisplayDialog("Failed to add scene", e.Message, "Ok");
+ }
+ });
+ }
+
+ private static void SelectScene(int index)
+ {
+ try
+ {
+ if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
+ return;
+
+ var scenes = SceneList.scenes[index];
+ var isScenePickerSetAsAdditive = ToolbarScenePickerSettings.IsScenePickerSetAsAdditive;
+
+ for (var i = 0; i < scenes.paths.Count; i++)
+ {
+ var path = scenes.paths[i];
+ var scene = SceneManager.GetSceneByPath(path);
+
+ if (scenes.isGroup)
+ {
+ if (isScenePickerSetAsAdditive || i != 0)
+ {
+ EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
+ var sceneIndex = SceneList.IndexOfPath(path, false);
+
+ if (sceneIndex != -1)
+ SceneList.selected.Add(sceneIndex);
+ }
+ else
+ {
+ EditorSceneManager.OpenScene(path, OpenSceneMode.Single);
+ var sceneIndex = SceneList.IndexOfPath(path, false);
+
+ SceneList.selected.Clear();
+
+ if (sceneIndex != -1)
+ SceneList.selected.Add(index);
+ }
+ }
+ else
+ {
+ if (scene.isLoaded)
+ {
+ if (SceneManager.sceneCount == 1)
+ return;
+
+ EditorSceneManager.CloseScene(scene, true);
+ SceneList.selected.Remove(index);
+ }
+ else if (isScenePickerSetAsAdditive)
+ {
+ EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
+ SceneList.selected.Add(index);
+ }
+ else
+ {
+ EditorSceneManager.OpenScene(path, OpenSceneMode.Single);
+ SceneList.selected.Clear();
+ SceneList.selected.Add(index);
+ }
+ }
+ }
+
+ GetSceneLabel();
+ }
+ catch (Exception e)
+ {
+ Debug.LogException(e);
+ }
+ finally
+ {
+ MainToolbar.Refresh("Toolbar/Scene");
+ }
+ }
+
+ private static string GetSceneLabel()
+ {
+ var builder = new StringBuilder();
+
+ if (SceneList.selected.Count != 0)
+ {
+ for (var i = 0; i < SceneList.selected.Count; i++)
+ {
+ if (i > 0)
+ builder.Append(", ");
+
+ builder.Append(SceneList.scenes[SceneList.selected[i]].shortname);
+ }
+ }
+ else
+ {
+ builder.Append("Unsaved scene(s)");
+ }
+
+ return builder.ToString();
+ }
+
+ public static void Refresh()
+ {
+ MainToolbar.Refresh("Toolbar/Scene");
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarScenePickerElement.cs.meta b/Editor/Toolbar/MainToolbarElements/MainToolbarScenePickerElement.cs.meta
new file mode 100644
index 0000000..55669ed
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarScenePickerElement.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 279f6b5a4bce42b6b1250f13a31a065c
+timeCreated: 1765023392
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarTimeScaleElement.cs b/Editor/Toolbar/MainToolbarElements/MainToolbarTimeScaleElement.cs
new file mode 100644
index 0000000..26fc670
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarTimeScaleElement.cs
@@ -0,0 +1,30 @@
+#if UNITY_6000_3_OR_NEWER
+using UnityEditor.Toolbars;
+using UnityEngine;
+using UnityEngine.Scripting;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ internal static class MainToolbarTimeScaleElement
+ {
+ [Preserve]
+ [MainToolbarElement("Toolbar/Time Scale", ussName = "", defaultDockIndex = 0, defaultDockPosition = MainToolbarDockPosition.Middle, menuPriority = 500)]
+ public static MainToolbarElement Draw()
+ {
+ var content = new MainToolbarContent("Time:", "Adjust Time.timeScale from [min;max] and snaps when value is approximately 1.0");
+ return new MainToolbarSlider(content, Time.timeScale, ToolbarTimeSettings.TimeScaleMinValue, ToolbarTimeSettings.TimeScaleMaxValue, OnTimeScaleValueChanged);
+ }
+
+ private static void OnTimeScaleValueChanged(float value)
+ {
+ value = Mathf.Clamp(value, ToolbarTimeSettings.TimeScaleMinValue, ToolbarTimeSettings.TimeScaleMaxValue);
+
+ if (Mathf.Abs(value - 1.0f) < 0.02f)
+ value = 1.0f;
+
+ if (!Mathf.Approximately(Time.timeScale, value))
+ Time.timeScale = value;
+ }
+ }
+}
+#endif
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarTimeScaleElement.cs.meta b/Editor/Toolbar/MainToolbarElements/MainToolbarTimeScaleElement.cs.meta
new file mode 100644
index 0000000..4473f00
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarTimeScaleElement.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 86d04559b6fc4260b33c97799a0e78e6
+timeCreated: 1765023773
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElements/MainToolbarUIElement.cs b/Editor/Toolbar/MainToolbarElements/MainToolbarUIElement.cs
new file mode 100644
index 0000000..dc44b86
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElements/MainToolbarUIElement.cs
@@ -0,0 +1,99 @@
+#if UNITY_6000_3_OR_NEWER
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using UnityEditor.Toolbars;
+using UnityEditorInternal;
+using UnityEngine;
+using UnityEngine.Scripting;
+using UTools = UnityEditor.Tools;
+
+namespace Module.NavigationTool.Editor.Toolbar
+{
+ internal static class MainToolbarUIElement
+ {
+ [Preserve]
+ [MainToolbarElement("Toolbar/UI", ussName = "", defaultDockIndex = 0, defaultDockPosition = MainToolbarDockPosition.Middle, menuPriority = 500)]
+ public static IEnumerable Draw()
+ {
+ var layer = 1 << LayerMask.NameToLayer("UI");
+ var toggleValue = (UTools.visibleLayers & layer) != 0;
+
+ return new List(2)
+ {
+ new MainToolbarToggle(new MainToolbarContent("UI", "Toggles UI visible layer in SceneView"), toggleValue, OnToggleValueChanged),
+ new MainToolbarDropdown(new MainToolbarContent("Select"), OnDropdownOpen)
+ };
+ }
+
+ private static void OnToggleValueChanged(bool result)
+ {
+ var layer = 1 << LayerMask.NameToLayer("UI");
+
+ if (result)
+ UTools.visibleLayers |= layer;
+ else
+ UTools.visibleLayers &= ~layer;
+
+ SceneView.RepaintAll();
+ }
+
+ private static void OnDropdownOpen(Rect rect)
+ {
+ var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
+ var canvases = prefabStage != null
+ ? prefabStage.prefabContentsRoot.GetComponentsInParent