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

Unity3D 自定义窗口

Unity3D 自定义窗口的实现。

自定义窗口

Unity3D 可以通过编写代码,扩展编辑器的菜单栏和窗口。

简单的功能可以直接一个菜单按钮实现,复杂的功能就需要绘制一个窗口展示更多的信息。

编辑器扩展的脚本,需要放在 Editor 文件夹中。

文件夹

菜单栏

首先,需要引用命名空间 UnityEditor,然后在类里编写静态方法,在方法的头顶上面添加 MenuItem,填写菜单栏的路径。

using UnityEditor;public class CustomizeWindow
{[MenuItem("自定义窗口/打开窗口")]public static void OpenWindow(){}
}

编译一下,就能看到多出了一个菜单栏选项。

菜单栏

窗口

需要继承 EditorWindow,通过 GetWindow 方法创建一个窗口对象,调用 Show 方法显示。

可以通过修改 titleContent 设置窗口标题。

这里的 GUIContent 需要引用命名空间 UnityEngine

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{[MenuItem("自定义窗口/打开窗口")]public static void OpenWindow(){// 创建窗口对象CustomizeWindow window = GetWindow<CustomizeWindow>();// 设置窗口标题window.titleContent = new GUIContent("自定义窗口");// 显示窗口window.Show();}
}

现在再去点击菜单栏的打开窗口按钮,就能显示自定义窗口了。

自定义窗口

按钮

现在窗口空荡荡的,可以先加两个按钮。

在窗口中绘制 UI 元素,需要写在生命周期函数 OnGUI 里面,使用 GUILayout.Button 创建按钮,使用 GUILayout.Height 设置按钮高度。

创建按钮的代码之所以放在 if 语句的条件判断里,是因为点击按钮后会返回一个布尔值,可以判断按钮是否被点击。

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{// ...void OnGUI(){if (GUILayout.Button("确定", GUILayout.Height(50))){}if (GUILayout.Button("取消", GUILayout.Height(50))){}}
}

现在窗口就有了两个按钮了。

绘制按钮

文本

使用 GUILayout.Label 绘制文本。

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{// ...void OnGUI(){GUILayout.Label("这是一个自定义的窗口,可以自由编写功能");// ...}
}

现在窗口有文本了。

绘制文本

文本输入框

使用 EditorGUILayout.TextField 绘制文本输入框,它有返回值,是输入框的内容。

可以在按钮里面打印一下文本输入框的内容。

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{// ...string input = "请输入...";void OnGUI(){// ...input = EditorGUILayout.TextField(input);if (GUILayout.Button("确定", GUILayout.Height(50))){Debug.Log("input = " + input);}// ...}
}

现在窗口有文本输入框了。

绘制文本输入框

样式

按钮文本的样式也可以自定义。

先定义 GUIStyle 变量,在 InitGUIStyle 方法中,分别对三种控件的样式进行初始化设置,然后传递给控件的第二个参数。

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{GUIStyle buttonStyle;GUIStyle labelStyle;GUIStyle textFieldStyle;// ...void OnGUI(){InitGUIStyle();GUILayout.Label("这是一个自定义的窗口,可以自由编写功能", labelStyle);input = EditorGUILayout.TextField(input, textFieldStyle);if (GUILayout.Button("确定", buttonStyle, GUILayout.Height(50))){Debug.Log("input = " + input);}if (GUILayout.Button("取消", buttonStyle, GUILayout.Height(50))){}}void InitGUIStyle(){if (buttonStyle == null){buttonStyle = new GUIStyle(GUI.skin.button);buttonStyle.fontSize = 14;buttonStyle.margin.left = 20;buttonStyle.margin.right = 20;buttonStyle.margin.top = 20;buttonStyle.margin.bottom = 20;}if (labelStyle == null){labelStyle = new GUIStyle(EditorStyles.boldLabel);labelStyle.fontSize = 14;labelStyle.margin.left = 20;labelStyle.margin.right = 20;labelStyle.margin.top = 20;labelStyle.margin.bottom = 20;}if (textFieldStyle == null){textFieldStyle = new GUIStyle(EditorStyles.toolbarTextField);textFieldStyle.fontSize = 14;textFieldStyle.fixedHeight = 30;textFieldStyle.margin.left = 20;textFieldStyle.margin.right = 20;textFieldStyle.margin.top = 20;textFieldStyle.margin.bottom = 20;}}
}

现在窗口焕然一新。

样式

布局

窗口内的控件可以调整摆放的布局。

例如,把两个垂直摆放的按钮,改成水平布局。

  • 在按钮代码的开头加上 EditorGUILayout.BeginHorizontal();
  • 在按钮代码的结尾加上 EditorGUILayout.EndHorizontal();

被这两行代码包围的控件,就会处于同一个水平布局之中。

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{// ...void OnGUI(){// ...EditorGUILayout.BeginHorizontal();if (GUILayout.Button("确定", buttonStyle, GUILayout.Height(50))){Debug.Log("input = " + input);}if (GUILayout.Button("取消", buttonStyle, GUILayout.Height(50))){}EditorGUILayout.EndHorizontal();}
}

现在两个按钮就在同一个水平布局之中了。

布局

间隔

使用 GUILayout.Space 绘制间隔。

例如,在文本输入框和按钮之间,加入 10 的间隔。

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{// ...void OnGUI(){// ...input = EditorGUILayout.TextField(input, textFieldStyle);GUILayout.Space(10);EditorGUILayout.BeginHorizontal();// ...}
}

现在文本输入框和按钮之间就不会那么贴近了。

间隔

滚动视图

滚动视图也是两行代码包围控件。

  • EditorGUILayout.BeginScrollView(scrollPos);
  • EditorGUILayout.EndScrollView();

不过滚动视图需要定义一个 Vector2 scrollPos,在滚动时记录当前的位置。

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{// ...GUIStyle scrollViewStyle;Vector2 scrollPos = Vector2.zero;void OnGUI(){// ...GUILayout.Label("搜索结果", labelStyle);scrollPos = EditorGUILayout.BeginScrollView(scrollPos, scrollViewStyle);GUILayout.Label("结果 1", labelStyle);GUILayout.Label("结果 2", labelStyle);EditorGUILayout.EndScrollView();}void InitGUIStyle(){// ...if (scrollViewStyle == null){scrollViewStyle = new GUIStyle(GUI.skin.scrollView);scrollViewStyle.fontSize = 14;scrollViewStyle.margin.left = 20;scrollViewStyle.margin.right = 20;scrollViewStyle.margin.top = 20;scrollViewStyle.margin.bottom = 20;}}
}

现在就有了一个展示结果列表的滚动视图。

滚动视图

弹窗

现在点按钮是没有反馈的,通常情况下可以给一个弹窗提示。

  • 弹窗附带一个确定和一个关闭按钮,使用 EditorUtility.DisplayDialog,返回 true 或者 false
  • 弹窗附带一个确定、一个取消、一个可选和一个关闭按钮,使用 EditorUtility.DisplayDialogComplex,返回 0、1、2

例如,在确定和取消按钮中添加弹窗提示。

using UnityEngine;
using UnityEditor;public class CustomizeWindow : EditorWindow
{// ...void OnGUI(){// ...if (GUILayout.Button("确定", buttonStyle, GUILayout.Height(50))){int id = EditorUtility.DisplayDialogComplex("温馨提示", "搜索完成", "okk", "oh no", "good");Debug.Log(id);}if (GUILayout.Button("取消", buttonStyle, GUILayout.Height(50))){bool flag = EditorUtility.DisplayDialog("温馨提示", "已取消", "okk");Debug.Log(flag);}}
}

现在点击确定按钮,弹出附带三个按钮和关闭按钮的弹窗。

复杂弹窗

点击取消按钮,弹出附带一个按钮和关闭按钮的弹窗。

简单弹窗

相关文章:

Unity3D 自定义窗口

Unity3D 自定义窗口的实现。 自定义窗口 Unity3D 可以通过编写代码&#xff0c;扩展编辑器的菜单栏和窗口。 简单的功能可以直接一个菜单按钮实现&#xff0c;复杂的功能就需要绘制一个窗口展示更多的信息。 编辑器扩展的脚本&#xff0c;需要放在 Editor 文件夹中。 菜单栏…...

dubbo:dubbo整合nacos实现服务注册中心、配置中心(二)

文章目录 0. 引言1. nacos简介及安装2. 注册中心实现3. 配置中心实现4. 源码5. 总结 0. 引言 之前我们讲解的是dubbozookeeper体系来实现微服务框架&#xff0c;但相对zookeeper很多企业在使用nacos, 并且nacos和dubbo都是阿里出品&#xff0c;所以具备一些天生的契合性&#…...

个人博客指路

Pudding 个人博客 比较懒&#xff0c;直接 github page 了&#xff0c;没国内代理加速。 欢迎大佬们&#xff0c;踩一踩 没做留言&#xff0c;觉得很鸡肋。有问题可以在本文底下评论、或者直接邮件...

【STM32 HAL】多串口printf重定向

【STM32 HAL】多串口printf重定向 前言单串口printf重定向原理实现CubeMX配置Keil5配置 多串口printf重定向 前言 在近期项目中&#xff0c;作者需要 STM32 同时向上位机和手机发送数据&#xff0c;传统的 printf 重定向只能输出到一个串口。本文介绍如何实现 printf 同时输出…...

帆软报表,达梦数据库驱动上传失败

1、按照正常操作新建数据库连接&#xff0c;上传准备好的达梦驱动时&#xff0c;提示如图一需要修改SystemConfig.driverUpload为true才可以。 2、FineDB存储了数据决策系统中除平台属性配置以外的所有信息。详情请参见&#xff1a; FineDB 数据库简介。 3、因此管理员可通过…...

CSS选择器的优先级是如何确定的?有哪些方法可以提高选择器的效率?

CSS选择器的优先级是如何确定的&#xff1f; CSS选择器的优先级决定了当多个选择器同时应用于一个元素时&#xff0c;哪个选择器将最终生效。CSS选择器的优先级由多个因素决定&#xff0c;主要包括以下几个方面&#xff1a; 特殊性&#xff08;Specificity&#xff09; 特殊性…...

【MySQL】基础入门(第二篇)

1.MySQL基本数据类型 数值类型 MySQL 支持所有标准 SQL 数值数据类型。 这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL 和 NUMERIC)&#xff0c;以及近似数值数据类型(FLOAT、REAL 和 DOUBLE PRECISION)。 关键字INT是INTEGER的同义词&#xff0c;关键字DEC是D…...

勇闯机器学习(第二关-数据集使用)

以下内容&#xff0c;皆为原创&#xff0c;重在无私分享高质量知识&#xff0c;制作实属不易&#xff0c;请点点关注。 好戏开场了~~~(这关涉及到了加载数据集的代码&#xff0c;下一关&#xff0c;教你们安装机器学习库) 一.数据集 这一关的目标 知道数据集被分为训练集和测…...

数据库学习(进阶)

数据库学习&#xff08;进阶&#xff09; Mysql结构:连接层&#xff1a;服务层&#xff08;核心层&#xff09;&#xff1a;存储引擎层&#xff1a;系统文件层&#xff1a; 存储引擎&#xff08;概述&#xff09;:存储引擎特点&#xff1a;InnoDB存储引擎&#xff1a;(为并发条…...

redis的数据结构——跳表(Skiplist)

跳表(Skiplist)是一种用于有序数据存储的高效数据结构,它在Redis中用于实现有序集合(Sorted Set,zset)的底层存储。当有序集合中的数据较多时,Redis会选择使用跳表来存储元素,以便在保持数据有序的同时提供高效的插入、删除、查找操作。 跳表的基本结构 跳表是一种多…...

Docker服务迁移

1 备份当前服务器上的 Docker 数据 1.1 停止 Docker 服务 为了确保数据一致性&#xff0c;在备份之前先停止 Docker 服务&#xff1a; sudo systemctl stop docker1.2 备份 Docker 数据 Docker 的数据通常位于 /var/lib/docker 目录。你可以使用 tar 命令将该目录压缩成一个…...

机器学习:逻辑回归实现下采样和过采样

1、概述 逻辑回归本身是一种分类算法&#xff0c;它并不涉及下采样或过采样操作。然而&#xff0c;在处理不平衡数据集时&#xff0c;这些技术经常被用来改善模型的性能。下采样和过采样是两种常用的处理不平衡数据集的方法。 2、下采样 1、概念 下采样是通过减少数量较多的类…...

React原理之Fiber双缓冲

前置文章&#xff1a; React原理之 React 整体架构解读React原理之整体渲染流程React原理之Fiber详解 -----读懂这一篇需要对 React 整体架构和渲染流程有大致的概念 &#x1f60a;----- 在前面的文章中&#xff0c;简单介绍了 Fiber 架构&#xff0c;也了解了 Fiber 节点的…...

机器学习笔记三-检测异常值

检测异常值是数据预处理中非常重要的一步&#xff0c;因为异常值可能会影响模型的训练效果&#xff0c;甚至导致错误的结论。以下是几种常见的检测异常值的方法&#xff1a; 1. 箱线图&#xff08;Box Plot&#xff09;&#xff1a; 箱线图是一种简单的统计图形&#xff0c;可…...

如何评估Redis的性能

导语 Redis是一款高性能的内存数据库&#xff0c;被广泛用于缓存、持久化、消息队列等各种场景。为了确保Redis的高性能运行&#xff0c;评估Redis的性能是非常重要的。本文将介绍如何评估Redis的性能&#xff0c;并从问题解决的角度探讨如何优化Redis的性能。 1. 性能评估指…...

RabbitMQ发布订阅模式Publish/Subscribe详解

订阅模式Publish/Subscribe 基于API的方式1.使用AmqpAdmin定制消息发送组件2.消息发送者发送消息3.消息消费者接收消息 基于配置类的方式基于注解的方式总结 SpringBoot整合RabbitMQ中间件实现消息服务&#xff0c;主要围绕3个部分的工作进行展开&#xff1a;定制中间件、消息发…...

Android8.1源码下对APK进行系统签名

在Android8.1上面对APK进行Android系统源码环境下的签名,发现签名时出现如下错误: Exception in thread "main" java.lang.ExceptionInInitializerError at org.conscrypt.OpenSSLBIOInputStream.(OpenSSLBIOInputStream. at org.conscrypt.OpenSSLX509Certificat…...

2024年城市客运安全员考试题库及答案

一、单选题 376.根据《机动车运行安全技术条件》&#xff08;GB7258---2017&#xff09;&#xff0c;每个应急出口应在其附近设有"应急出口"字样&#xff0c;字体高度应大于或等于&#xff08;&#xff09;mm。 A.20 B.30 C.40 D.50 答案&#xff1a;C 377.根…...

全网最全面的Nginx内容(理论与实践相结合)

一、Web服​​务 1.1 web服务访问流程 1.2 Web服务 1.2.1 Web服务器分类 Web服务分为Apache和Nginx 1.2.2 Apache经典的Web服务器 1.2.2.1 Apache介绍 Apache HTTP Server&#xff08;简称Apache&#xff09;是Apache软件基金会的一个开放源码的网页服务器&#xff0c;可以…...

(七)Flink Watermark

Flink 的 Watermark 是用来标识数据流中的一个时间点。Watermark 的设计是为了解决乱序数据处理的问题,尤其是涉及到多个分区的 Kafka 消费者时。在 Watermark 的作用下,即使某些数据出现了延迟到达的情况,也不会导致整个处理流程的中断。此外,Watermark 还能防止过期的数据…...

dotAI:将AI能力环境化,打造可配置的智能开发工作流

1. 项目概述&#xff1a;当AI成为你的“数字管家”最近在GitHub上看到一个挺有意思的项目&#xff0c;叫udecode/dotai。乍一看这个标题&#xff0c;你可能和我最初的反应一样&#xff0c;有点摸不着头脑。dotai&#xff1f;是“点AI”的意思吗&#xff1f;它和.env文件那种“点…...

构建高质量Awesome清单:开源项目精选与维护实践指南

1. 项目概述&#xff1a;为什么我们需要一个“Awesome”清单&#xff1f;在开源的世界里&#xff0c;信息过载是每个开发者、技术爱好者乃至项目经理都面临的共同挑战。每天&#xff0c;GitHub、GitLab等平台上都会涌现出成千上万个新项目&#xff0c;从精巧的工具库到庞大的系…...

免费开源字体编辑器终极指南:5个核心模块带你从零到专业设计

免费开源字体编辑器终极指南&#xff1a;5个核心模块带你从零到专业设计 【免费下载链接】fontforge Free (libre) font editor for Windows, Mac OS X and GNULinux 项目地址: https://gitcode.com/gh_mirrors/fo/fontforge 想要免费编辑字体却找不到合适的工具&#x…...

AI如何学习科学品味:从多模态特征到科研评估系统构建

1. 项目概述&#xff1a;当AI开始学习“科学品味” 最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“AI-Can-Learn-Scientific-Taste”。光看名字&#xff0c;你可能觉得这又是一个关于AI模型训练或者科学计算的常规项目。但点进去仔细琢磨&#xff0c;你会发现它的野心远…...

从零制作LED智能面具:三种方案详解与避坑指南

1. 项目概述&#xff1a;三种不同段位的LED化妆面具制作如果你对闪烁的灯光和可穿戴电子设备着迷&#xff0c;一直想亲手做一个能在派对或演出中吸引眼球的智能面具&#xff0c;但又觉得无从下手&#xff0c;那这个项目就是为你准备的。我花了几个周末的时间&#xff0c;从最简…...

别再只怪USB线了!i.MX6Q用Mfgtools烧录rootfs.tar.bz2报错的深层硬件排查指南

i.MX6Q烧录故障的硬件级诊断&#xff1a;从USB OTG冲突到电源完整性排查 当Mfgtools在rootfs.tar.bz2传输阶段突然报错"Push error"或"No Device Connected"时&#xff0c;多数开发者会本能地检查USB线缆或驱动配置。但真正棘手的故障往往潜伏在硬件交互层…...

不止于安装:在 Ubuntu 20.04 上为 GAMMA 配置完整的 InSAR 科研环境(含 Python 依赖)

不止于安装&#xff1a;在 Ubuntu 20.04 上为 GAMMA 配置完整的 InSAR 科研环境&#xff08;含 Python 依赖&#xff09; 当你在Ubuntu 20.04上成功安装GAMMA后&#xff0c;可能会发现这仅仅是开始。真正的挑战在于构建一个完整、稳定的科研环境&#xff0c;让InSAR数据处理流程…...

深入解析瑞芯微RK3399/RK3288平台ISP驱动:从V4L2框架到Camera Sensor联动

1. 项目概述 在嵌入式Linux开发&#xff0c;特别是涉及多媒体处理的项目中&#xff0c;图像信号处理器&#xff08;ISP&#xff09;驱动的理解往往是打通摄像头应用链路的关键一环&#xff0c;也是很多开发者感觉“黑盒”最多的地方。最近在调试基于瑞芯微RK3399和RK3288平台的…...

pgwatch2监控指标详解:从基础性能到高级洞察

pgwatch2监控指标详解&#xff1a;从基础性能到高级洞察 【免费下载链接】pgwatch2 PostgreSQL metrics monitor/dashboard 项目地址: https://gitcode.com/gh_mirrors/pg/pgwatch2 pgwatch2是一款功能强大的PostgreSQL metrics monitor/dashboard工具&#xff0c;它能够…...

demo-magic常见问题解决:pv工具安装和终端兼容性完全指南

demo-magic常见问题解决&#xff1a;pv工具安装和终端兼容性完全指南 【免费下载链接】demo-magic A handy shell script that enables you to write repeatable demos in a bash environment. 项目地址: https://gitcode.com/gh_mirrors/de/demo-magic demo-magic是一个…...