当前位置: 首页 > news >正文

第四章自定义编辑器窗口_创建and打开and自定义窗口(3/11)

前言

书本里的这章节主要介绍了自定义窗口,涉及到EditorWindow,PopupWindow,GenericMenus和ScriptsWizard类。还介绍了扩展默认窗口

下面是对他们的一些比较介绍

类名最佳用途生命周期交互复杂度
EditorWindow长期使用的工具面板持久化(手动关闭)高(完整 UI)
PopupWindow临时浮层控件短暂(自动关闭)中(轻量控件)
GenericMenu动态右键/下拉菜单瞬时(点击后消失)低(纯文本)
ScriptableWizard旧版向导流程(已不推荐)中等(任务驱动)中(分页表单)
Unity 版本EditorWindowPopupWindowGenericMenuScriptableWizard
2017.x✅ 完整支持✅ 完整支持✅ 完整支持⚠️ 部分支持
2019.x✅ 完整支持✅ 完整支持✅ 完整支持❌ 已弃用
2020.x+✅ 完整支持✅ 完整支持✅ 完整支持❌ 已移除

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每帧(Repaint 事件)绘制界面、处理交互逻辑
Update每帧(与游戏 Update 同步)实时更新数据、刷新视图
OnSelectionChange场景或 Project 视图选中对象变化时同步显示当前选中内容
OnFocus / OnLostFocus窗口获得 / 失去焦点时启用/停用输入监听、更新标题栏
OnHierarchyChange场景层级结构变化时刷新节点列表、重新构建树形视图
OnProjectChange资源导入 / 删除 / 移动时重新加载资源列表、更新引用
using UnityEditor;
using UnityEngine;/// <summary>
/// 这个脚本演示了如何在编辑器窗口中使用OnGUI方法绘制UI控件  
/// </summary>
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 如何创建弹出窗口

  1. 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("弹出窗口已关闭");}   
}

效果
在这里插入图片描述

  1. 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("弹出窗口已关闭");}
}

效果
在这里插入图片描述

http://www.lryc.cn/news/598273.html

相关文章:

  • vue3升级了哪些重要功能
  • 边缘计算场景的轻量化实践_将 Nginx 打包为便携式 AppImage
  • 从提示词,工具,上下文管理三个角度看OpenManus
  • 嵌入式学习-(李宏毅)机器学习(2)-day29
  • go语言基础教程:【1】基础语法:变量
  • Spring Cloud OpenFeign 常用注解_笔记
  • 在 Alpine Linux 中创建虚拟机时 Cgroup 挂在失败的现象
  • 弧焊机器人减少气体消耗攻略
  • SSL 证书与 HTTPS 的关系:一文理清核心关联
  • 离线环境下如何优雅地部署 Mentor Questa
  • Mysql命令show processlist
  • OpenCV —— color_matrix_numpy_mat_reshape
  • 嵌入式Linux:线程的创建、终止、回收、取消和分离
  • C# system.diagnostics.debug.writeline 不在输出窗口显示
  • 测试学习之——Pytest Day5
  • Java泛型初始化ArrayList<String>()和ArrayList<>()的区别
  • 【C++】简单学——list类
  • HTTP和HTTPS复习
  • Ethereum: 从零到一为DApp开发搭建专属的私有测试网络
  • USRP X440
  • LeetCode 10:正则表达式匹配
  • Python:开启机器学习的魔法之门
  • 无源域自适应综合研究【2】
  • Android Telephony UrspRule 介绍
  • EVAL长度限制突破方法
  • C#_定时器_解析
  • Flink-1.19.0源码详解7-Flink集群端调度
  • ubuntu安装teams解决方法
  • 大模型回复数据标注优化方案
  • 系统架构师:系统安全与分析-思维导图