Unity ToolBar拓展开源库

Unity-Editor-Toolbox

这个开源库里包含了很多Editor拓展,本篇仅介绍Toolbar的拓展,关于Toolbar的介绍:https://github.com/arimger/Unity-Editor-Toolbox#toolbar-

详细代码:https://github.com/arimger/Unity-Editor-Toolbox/blob/master/Assets/Editor%20Toolbox/Editor/ToolboxEditorToolbar.cs

如果只需要Toolbar拓展,只需要把这一个脚本拷贝到工程下Editor目录,再建一个添加Toolbar菜单的脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using Toolbox.Editor;

[UnityEditor.InitializeOnLoad]
public static class MyEditorUtility
{
static MyEditorUtility()
{
ToolboxEditorToolbar.AddToolbarButton(new ToolbarButton(() => Debug.Log("1"), new GUIContent("1")));
ToolboxEditorToolbar.AddToolbarButton(new ToolbarButton(() => Debug.Log("2"), new GUIContent("2")));
ToolboxEditorToolbar.AddToolbarButton(new ToolbarButton(() => Debug.Log("3"), new GUIContent("3")));
ToolboxEditorToolbar.AddToolbarButton(new ToolbarButton(() => Debug.Log("4"), new GUIContent("4")));
ToolboxEditorToolbar.AddToolbarButton(new ToolbarButton(() => Debug.Log("5"), new GUIContent("5")));
}
}

效果图

这个仓库的菜单只会添加在左侧。

经过测试,按照仓库设计的按钮大小,只够放置7个按钮,当然各个unity版本的Toolbar中间的宽度不一,会有点差异。

CustomToolbar

这个仓库实现的自定义Toolbar示意图如下:

仓库拓展了5个功能,是基于unity-toolbar-extender开发的。这个库支持往左右两边添加自定义菜单。

这五个功能包含在下图的脚本中

保留ToolbarCallback和ToolbarExtender脚本,通过往ToolbarExtender.RightToolbarGUI和ToolbarExtender.LeftToolbarGUI添加Action,即可绘制自定义的菜单。

unity-toolbar-extender

CustomToolbar库是基于unity-toolbar-extender的,那么如何使用跟前面讲的一样。这个库自带的是

  • 切换场景运行
  • Focus Scene开关,如果打开,则运行游戏后,自动Focus Scene View

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public static class ToolbarCallback
{
//反射获取Toolbar类型
static Type m_toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
//反射获取GUIView类型
static Type m_guiViewType = typeof(Editor).Assembly.GetType("UnityEditor.GUIView");
static PropertyInfo m_viewVisualTree = m_guiViewType.GetProperty("visualTree",
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
static FieldInfo m_imguiContainerOnGui = typeof(IMGUIContainer).GetField("m_OnGUIHandler",
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
static ScriptableObject m_currentToolbar;

/// <summary>
/// Callback for toolbar OnGUI method.
/// </summary>
public static Action OnToolbarGUI;

static ToolbarCallback()
{
EditorApplication.update -= OnUpdate;
EditorApplication.update += OnUpdate;
}

static void OnUpdate()
{
// Relying on the fact that toolbar is ScriptableObject and gets deleted when layout changes
if (m_currentToolbar == null)
{
//获取到原有的Toolbar
var toolbars = Resources.FindObjectsOfTypeAll(m_toolbarType);
m_currentToolbar = toolbars.Length > 0 ? (ScriptableObject) toolbars[0] : null;
if (m_currentToolbar != null)
{
//获取Toolbar的VisualTree
var visualTree = (VisualElement) m_viewVisualTree.GetValue(m_currentToolbar, null);

// Get first child which 'happens' to be toolbar IMGUIContainer
var container = (IMGUIContainer) visualTree[0];

//重新注册handler
var handler = (Action) m_imguiContainerOnGui.GetValue(container);
handler -= OnGUI;
handler += OnGUI;
m_imguiContainerOnGui.SetValue(container, handler);
}
}
}

//自定义的绘制函数
static void OnGUI()
{
var handler = OnToolbarGUI;
if (handler != null) handler();
}
}