第四章自定义编辑器窗口_创建and打开and自定义窗口(3/11)
前言
书本里的这章节主要介绍了自定义窗口,涉及到EditorWindow,PopupWindow,GenericMenus和ScriptsWizard类。还介绍了扩展默认窗口
下面是对他们的一些比较介绍
4.1 如何创建新的编辑器窗口
Unity 的使用是在不同的编辑器窗口中进行的,例如Scene、Game、Project、HierarchyInspector、Console 等,除了这些默认的编辑器窗口,开发者可以创建新的编辑器窗口并定义其中的内容,创建的新的编辑器窗口类需要继承EditorWindow。(这是原文)
4.1.1 打开新创建的编辑器窗口
打开编辑器窗口需要一个菜单路径,例如打开控制台窗口的菜单路径为WindGenera/Console,所以首先要为新创建的编辑器窗口使用Menultem 提供一个窗口入口。调用 EditorWindow 类中的静态方法 GetWindowO可以获取指定类型的窗口实例。
using UnityEngine;using UnityEditor;public class MyEditorWindow : EditorWindow{ [MenuItem(\"Example/My Editor Window\")] public static void ShowWindow() { // 创建或显示编辑器窗口 MyEditorWindow window = GetWindow<MyEditorWindow>(\"窗口标题\"); window.minSize = new Vector2(300, 200); // 设置最小窗口大小 window.maxSize = new Vector2(1920, 1080); // 设置最大窗口大小 window.Show(); }}
4.1.2 定义编辑器窗口中的GUI内容
OnEnable
OnDisable
OnDestroy
OnGUI
Update
OnSelectionChange
OnFocus
/ OnLostFocus
OnHierarchyChange
OnProjectChange
using UnityEditor;using UnityEngine;/// /// 这个脚本演示了如何在编辑器窗口中使用OnGUI方法绘制UI控件 /// public class MyEditorWindow_CustomOnGUI : EditorWindow{ [MenuItem(\"Example/Show Editor Window CustomeOnGUI\")] public static void ShowWindow() { // 创建或显示编辑器窗口 MyEditorWindow_CustomOnGUI window = GetWindow<MyEditorWindow_CustomOnGUI>(\"使用OnGUI绘制UI控件\"); window.minSize = new Vector2(300, 300); // 设置最小窗口大小 window.maxSize = new Vector2(1920, 1080); // 设置最大窗口大小 window.Show(); } private void OnGUI() { GUILayout.Button(\"按钮\"); } private void OnFocus() { Debug.Log(\"OnFocus\"); } private void OnLostFocus() { Debug.Log(\"OnLostFocus\"); } private void OnHierarchyChange() { Debug.Log(\"OnHierarchyChang\"); } private void OnInspectorUpdate() { Debug.Log(\"OnInspecotrUpdate\"); } private void OnProjectChange() { Debug.Log(\"OnProjectChang\"); } private void OnSelectionChange() { Debug.Log(\"OnSelectionChang\"); } private void OnValidate() { Debug.Log(\"OnValidate\"); } private void OnDisable() { Debug.Log(\"OnDisable\"); } private void OnDestroy() { Debug.Log(\"OnDestroy\"); }}
4.1.3 如何创建弹出窗口
- PopupWindow
PopupWindow 弹出窗口不可以被拖动,也无法调节大小,并且还会在失去焦点时自动关闭。打开弹出窗口需要调用 PopupWindow中的静态方法Show,代码如下:
using System.Collections;using System.Collections.Generic;using UnityEditor;using UnityEngine;public class MyEditorWindow_PopupWindow : EditorWindow{ [MenuItem(\"Example/MyEditorWindow_PopupWindow\")] public static void Open() { MyEditorWindow_PopupWindow window = GetWindow<MyEditorWindow_PopupWindow>(); window.titleContent = new GUIContent(\"窗口标题\"); window.minSize = new Vector2(300f, 300f); window.maxSize = new Vector2(1920f, 1080f); window.Show(); } private Rect examplePopuWindowRect; private void OnGUI() { // 绘制一个按钮,点击后弹出窗口 if (GUILayout.Button(\"打开弹出窗口\")) { PopupWindow.Show( new Rect(100, 100, 200, 200), new ExamplePopupWindowContent( new Vector2(position.width -6f,100f))); } if (Event.current.type == EventType.Repaint) { examplePopuWindowRect = GUILayoutUtility.GetLastRect(); } }}public class ExamplePopupWindowContent : PopupWindowContent{ //窗口尺寸 private Vector2 windowSize; //滚动值 private Vector2 scroll; public ExamplePopupWindowContent(Vector2 windowSize) { this.windowSize = windowSize; } public override Vector2 GetWindowSize() { return new Vector2(200f, 200f); } public override void OnGUI(Rect rect) { // 在弹出窗口中绘制内容 GUILayout.Label(\"这是一个弹出窗口\"); if (GUILayout.Button(\"关闭\")) { editorWindow.Close(); } } public override void OnOpen() { base.OnOpen(); Debug.Log(\"弹出窗口已打开\"); } public override void OnClose() { base.OnClose(); Debug.Log(\"弹出窗口已关闭\"); } }
效果
- GenericMenu
使用 GencricMcnu 同样可以创建一个弹出窗口,与 PopupWindow 的区别在于,以在弹出窗口内开启水平或垂直布局,创建各类型的交互控件,还可以灵活地绘制编素、而前者弹出的窗口只是一个下拉菜单,它包含的公共方法。
AddItem(GUIContent content, bool on, GenericMenu.MenuFunction func)
content
: 菜单项显示内容on
: 是否显示选中标记func
: 点击回调方法menu.AddItem(new GUIContent(\"保存\"), false, Save)
AddItem(GUIContent content, bool on, GenericMenu.MenuFunction2 func, object userData)
userData
: 传递给回调的自定义数据menu.AddItem(new GUIContent(\"删除\"), false, (data) => Delete(data), obj)
AddDisabledItem(GUIContent content, bool on)
content
: 菜单项显示内容on
: 是否显示选中标记menu.AddDisabledItem(new GUIContent(\"需要专业版\"))
AddSeparator(string path)
path
: 分隔符位置路径menu.AddSeparator(\"编辑/\")
ShowAsContext()
menu.ShowAsContext()
DropDown(Rect rect)
rect
: 显示位置的矩形区域menu.DropDown(buttonRect)
allowDuplicateNames
menu.allowDuplicateNames = true
using UnityEditor;using UnityEngine;public class MyEditorWindow_PopupWindow_GerericMenu : EditorWindow{ [MenuItem(\"Example/MyEditorWindow_PopupWindow_GerericMenu\")] public static void Open() { MyEditorWindow_PopupWindow_GerericMenu window = GetWindow<MyEditorWindow_PopupWindow_GerericMenu>(); window.titleContent = new GUIContent(\"窗口标题\"); window.minSize = new Vector2(300f, 300f); window.maxSize = new Vector2(1920f, 1080f); window.Show(); } private Rect examplePopuWindowRect; private void OnGUI() { // 绘制一个按钮,点击后弹出窗口 if (GUILayout.Button(\"打开弹出窗口\")) { PopupWindow.Show( new Rect(100, 100, 200, 200), new ExamplePopupWindowContent( new Vector2(position.width - 6f, 100f))); } if (Event.current.type == EventType.Repaint) { examplePopuWindowRect = GUILayoutUtility.GetLastRect(); } if (GUILayout.Button(\"Button\")) { GenericMenu gm = new GenericMenu(); //添加菜单项 gm.AddItem(new GUIContent(\"菜单项1\"), false, () => Debug.Log(\"菜单项1被点击\")); //添加分隔符 参数传空字符串表示在一级菜单中添加分隔符 gm.AddSeparator(string.Empty); //添加不可交互菜单项 gm.AddDisabledItem(new GUIContent(\"Memu2\")); //通过\'/\'可添加子菜单项 gm.AddItem(new GUIContent(\"Menu3/SubMenu1\"), false, () => Debug.Log(\"Select SubMenu1\")); //在子菜单中添加分隔符 gm.AddSeparator(\"Menu3/\"); gm.AddItem(new GUIContent(\"Menu3/SubMenu2\"), false, () => Debug.Log(\"Select SubMenu2\")); //显示菜单 gm.ShowAsContext(); } }}public class ExamplePopupWindowContent_1 : PopupWindowContent{ //窗口尺寸 private Vector2 windowSize; //滚动值 private Vector2 scroll; public ExamplePopupWindowContent_1(Vector2 windowSize) { this.windowSize = windowSize; } public override Vector2 GetWindowSize() { return new Vector2(200f, 200f); } public override void OnGUI(Rect rect) { // 在弹出窗口中绘制内容 GUILayout.Label(\"这是一个弹出窗口\"); if (GUILayout.Button(\"关闭\")) { editorWindow.Close(); } } public override void OnOpen() { base.OnOpen(); Debug.Log(\"弹出窗口已打开\"); } public override void OnClose() { base.OnClose(); Debug.Log(\"弹出窗口已关闭\"); }}
效果