在编辑器顶部的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