Unity編輯器拓展之三十:拓展UnityToolBar

博客遷移

個人博客站點,歡迎訪問,www.jiingfengji.tech

本文地址

Unity ToolBar拓展開源庫

  • https://github.com/arimger/Unity-Editor-Toolbox.git
  • https://github.com/smkplus/CustomToolbar.git
  • https://github.com/marijnz/unity-toolbar-extender.git

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菜單的腳本。

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

核心代碼

    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();
        }
    }

以上知識分享,如有錯誤,歡迎指出,共同學習,共同進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章