Created
December 28, 2025 13:08
-
-
Save adammyhre/2fbf3c95228b76342487828919570ce7 to your computer and use it in GitHub Desktop.
Unity 6.3 Custom Main Toolbar
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 UnityEditor; | |
| using UnityEngine; | |
| using UnityEngine.UIElements; | |
| using UnityUtils; // https://github.com/adammyhre/Unity-Utils | |
| public static class MainToolbarElementStyler { | |
| public static void StyleElement<T>(string elementName, System.Action<T> styleAction) where T : VisualElement { | |
| EditorApplication.delayCall += () => { | |
| ApplyStyle(elementName, (element) => { | |
| T targetElement = null; | |
| if (element is T typedElement) { | |
| targetElement = typedElement; | |
| } else { | |
| targetElement = element.Query<T>().First(); | |
| } | |
| if (targetElement != null) { | |
| styleAction(targetElement); | |
| } | |
| }); | |
| }; | |
| } | |
| static void ApplyStyle(string elementName, System.Action<VisualElement> styleCallback) { | |
| var element = FindElementByName(elementName); | |
| if (element != null) { | |
| styleCallback(element); | |
| } | |
| } | |
| static VisualElement FindElementByName(string name) { | |
| var windows = Resources.FindObjectsOfTypeAll<EditorWindow>(); | |
| foreach (var window in windows) { | |
| var root = window.rootVisualElement; | |
| if (root == null) continue; | |
| VisualElement element; | |
| if ((element = root.FindElementByName(name)) != null) return element; | |
| if ((element = root.FindElementByTooltip(name)) != null) return element; | |
| } | |
| return null; | |
| } | |
| } |
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 UnityEditor.Toolbars; | |
| using UnityEngine; | |
| using UnityEngine.UIElements; | |
| public class MainToolbarTimescaleSlider { | |
| const float k_minTimeScale = 0f; | |
| const float k_maxTimeScale = 5f; | |
| [MainToolbarElement("Timescale/Slider", defaultDockPosition = MainToolbarDockPosition.Middle)] | |
| public static MainToolbarElement TimeSlider() { | |
| var content = new MainToolbarContent("Time Scale", "Time Scale"); | |
| var slider = new MainToolbarSlider(content, Time.timeScale, k_minTimeScale, k_maxTimeScale, OnSliderValueChanged); | |
| slider.populateContextMenu = (menu) => { | |
| menu.AppendAction("Reset", _ => { | |
| Time.timeScale = 1f; | |
| MainToolbar.Refresh("Timescale/Slider"); | |
| }); | |
| }; | |
| MainToolbarElementStyler.StyleElement<VisualElement>("Timescale/Slider", (element) => { | |
| element.style.paddingLeft = 10f; | |
| }); | |
| return slider; | |
| } | |
| static void OnSliderValueChanged(float newValue) { | |
| Time.timeScale = newValue; | |
| } | |
| } |
In principle, it worked quite well.
static VisualElement FindElementByName(string name)
{
var nameWithoutSpace = name.Replace(" ", "");
var windows = Resources.FindObjectsOfTypeAll<EditorWindow>();
foreach (var window in windows)
{
var root = window.rootVisualElement;
if (root == null) continue;
VisualElement element;
if ((element = root.FindElementByName(name)) != null) return element;
if ((element = root.FindElementByName(nameWithoutSpace)) != null) return element;
if ((element = root.FindElementByTooltip(name)) != null) return element;
}
return null;
}
And one more thing that wasn't in the video, if for example you need to combine a slider and a button into one tool, then you need to return not MainToolbarElement but IEnumerable'<'MainToolbarElement> where to each yield return add the desired element
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Regarding the MainToolbarElementStyler.StyleElement method, if the element name contains spaces, unfortunately it will not work.