扩展unity顶部Toolbar,增加自定义按钮

在编辑器顶部的ToolBar增加自定义的按钮,效果如下
在这里插入图片描述代码如下,自取吧
效果就是,在编辑器下,不管你在什么场景,点击运行的时候,都会跳转到GameStart场景来启动
支持unity2018以上各种版本

#if UNITY_EDITOR
using System.Reflection;
using UnityEditor;
using UnityEngine;
using System;
using UnityEngine.SceneManagement;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif

namespace EditorExtend
{
    
    
    [InitializeOnLoad]
    public static class ToolbarExtend
    {
    
    
        private static readonly Type containterType = typeof(IMGUIContainer);
        private static readonly Type TOOLBAR_TYPE = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.Toolbar");
        private static readonly Type GUIVIEW_TYPE = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.GUIView");
#if UNITY_2020_1_OR_NEWER
        private static readonly Type backendType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.IWindowBackend");

        private static readonly PropertyInfo guiBackend = GUIVIEW_TYPE.GetProperty("windowBackend",
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
        private static readonly PropertyInfo VISUALTREE_PROPERTYINFO = backendType.GetProperty("visualTree",
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);


#else
        private static readonly PropertyInfo VISUALTREE_PROPERTYINFO = GUIVIEW_TYPE.GetProperty("visualTree",
           BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
#endif
        private static readonly FieldInfo ONGUI_HANDLER_FIELDINFO = containterType.GetField("m_OnGUIHandler",
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);


        private static ScriptableObject ms_CurrentToolbar;
        private static int ms_ToolIconCount;
        private static GUIStyle ms_CommandStyle;
        private static GUIStyle ms_CommandButtonStyle;
        private const string START_GAME_OPTION = "START_GAME_OPTION";
        private static string startSceneName = "GameStart";

        /// <summary>
        /// 游戏启动时调用(仅只一次)
        /// </summary>
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        static void OnStartGame()
        {
    
    
#if UNITY_EDITOR
            Scene scene = SceneManager.GetActiveScene ();
            if (!scene.name.Equals(startSceneName))
            {
    
    
                if (UnityEditor.EditorPrefs.GetBool(START_GAME_OPTION))
                {
    
    
                    SceneManager.LoadScene(startSceneName);
                }
            }
            UnityEditor.EditorPrefs.SetBool(START_GAME_OPTION, false);
            AssetDatabase.Refresh();

#endif
        }

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

        public static GUIStyle GetCommandButtonStyle()
        {
    
    
            return ms_CommandButtonStyle;
        }

        private static void OnUpdate()
        {
    
    
            if (ms_CurrentToolbar != null)
            {
    
    
                return;
            }

            UnityEngine.Object[] toolbars = Resources.FindObjectsOfTypeAll(TOOLBAR_TYPE);
            ms_CurrentToolbar = toolbars.Length > 0 ? (ScriptableObject)toolbars[0] : null;
            if (ms_CurrentToolbar != null)
            {
    
    


#if UNITY_2020_1_OR_NEWER
                var backend = guiBackend.GetValue(ms_CurrentToolbar);
                var elements = VISUALTREE_PROPERTYINFO.GetValue(backend, null) as VisualElement;
#else
                var elements = VISUALTREE_PROPERTYINFO.GetValue(ms_CurrentToolbar, null) as VisualElement;
#endif

#if UNITY_2019_1_OR_NEWER
                var container = elements[0];
#else
            var container = elements[0] as IMGUIContainer;
#endif
                var handler = ONGUI_HANDLER_FIELDINFO.GetValue(container) as Action;
                handler -= OnGUI;
                handler += OnGUI;
                ONGUI_HANDLER_FIELDINFO.SetValue(container, handler);
            }
        }
        private static void OnGUI()
        {
    
    
            var rect = new Rect(800, 3, 40, 24);
            int space = 10;
            if (GUI.Button(rect, "运行"))
            {
    
    
                EditorPrefs.SetBool(START_GAME_OPTION, true);
                EditorApplication.ExecuteMenuItem("Edit/Play");
            }
            rect.x += rect.width + space;
        }

        // 执行命令行
        public static void ProcessCommand(string command, string argument, bool waitForExit = true)
        {
    
    
            System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(command);
            info.Arguments = argument;
            info.CreateNoWindow = false;
            info.ErrorDialog = true;
            info.UseShellExecute = true;

            if (info.UseShellExecute)
            {
    
    
                info.RedirectStandardOutput = false;
                info.RedirectStandardError = false;
                info.RedirectStandardInput = false;
            }
            else
            {
    
    
                info.RedirectStandardOutput = true;
                info.RedirectStandardError = true;
                info.RedirectStandardInput = true;
                info.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8;
                info.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
            }

            System.Diagnostics.Process process = System.Diagnostics.Process.Start(info);

            if (!info.UseShellExecute)
            {
    
    
                Debug.Log(process.StandardOutput);
                Debug.Log(process.StandardError);
            }
            if (waitForExit)
                process.WaitForExit();
            process.Close();
        }
    }
}
#endif

猜你喜欢

转载自blog.csdn.net/weixin_42562717/article/details/129443395