当前位置: 首页 > 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 还能防止过期的数据…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...