Extend the Unity top Toolbar and add custom buttons

Add a custom button to the ToolBar at the top of the editor. The effect is as follows
Insert image description here. The code is as follows. Get it yourself.
The effect is that in the editor, no matter what scene you are in, when you click Run, it will jump to the GameStart scene to start.
Support unity2018 and above. various versions

#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

Guess you like

Origin blog.csdn.net/weixin_42562717/article/details/129443395