2024-02-13 Unity 编辑器开发之编辑器拓展4 —— EditorGUIUtility

news2025/4/13 17:59:18

文章目录

  • 1 EditorGUIUtility 介绍
  • 2 加载资源
    • 2.1 Eidtor Default Resources
    • 2.2 不存在返回 null
    • 2.3 不存在则报错
    • 2.4 代码示例
  • 3 搜索框查询、对象选中提示
    • 3.1 ShowObjectPicker
    • 3.2 PingObject
    • 3.3 代码示例
  • 4 窗口事件传递、坐标转换
    • 4.1 CommandEvent
    • 4.2 GUIPoint 和 ScreenPoint
    • 4.3 代码示例
  • 5 指定区域使用对应鼠标指针
    • 5.1 AddCursorRect
  • 6 绘制色板、绘制曲线
    • 6.1 DrawColorSwatch
    • 6.2 DrawCurveSwatch
    • 6.3 代码示例
    • 6.4 更多 API

1 EditorGUIUtility 介绍

​ Utility 意思为“实用”,EditorGUIUtility 是 EditorGUI 中的一个实用工具类,提供 EditorGUI 相关的其他辅助 API,下面仅介绍其中相对常用的内容。

​ 官方文档:https://docs.unity3d.com/ScriptReference/EditorGUIUtility.html。

2 加载资源

2.1 Eidtor Default Resources

​ Editor Default Resources 也是 Unity 中的特殊文件夹,主要作用是放置提供给 EditorGUIUtility 加载的资源。

​ 要使用 EditorGUIUtility 公共类来加载资源,需要将资源放置在 Editor Default Resources 文件夹中(命名需要带空格)。

2.2 不存在返回 null

  • API:EditorGUIUtility.Load
  • 注意事项:
    1. 只能加载 Assets/Editor Default Resources/ 文件夹下的资源。
    2. 加载资源时,需要填写资源后缀名。

2.3 不存在则报错

  • API:EditorGUIUtility.LoadRequired
  • 注意事项:
    1. 只能加载 Assets/Editor Default Resources/ 文件夹下的资源。
    2. 加载资源时,需要填写资源后缀名。

2.4 代码示例

image-20240213124410288
public class Lesson12 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson12/EditorGUIUtility学习面板")]
    private static void OpenLesson12() {
        Lesson12 win = EditorWindow.GetWindow<Lesson12>("EditorGUIUtility学习面板");
        win.Show();
    }

    private Texture img;
    private Texture img2;

    private void OnGUI() {

        // 加载资源(如果资源不存在返回null)
        if (GUILayout.Button("加载编辑器图片资源"))
            img = EditorGUIUtility.Load("EditorTeach.png") as Texture;
        if (img != null)
            GUI.DrawTexture(new Rect(0, 50, 160, 90), img);

        if (GUILayout.Button("加载编辑器图片资源"))
            img2 = EditorGUIUtility.LoadRequired("EditorTeach.png") as Texture;
        if (img2 != null)
            GUI.DrawTexture(new Rect(0, 150, 160, 90), img2);
    }
}
image-20240213124345161

3 搜索框查询、对象选中提示

3.1 ShowObjectPicker

  • 作用:弹出一个搜索窗口,用于选择自己想要的资源。

  • API:EditorGUIUtility.ShowObjectPicker<资源类型>(默认被选中的对象, 是否允许查找场景对象, "查找对象名称过滤", 0);

    1. 参数 1:默认被选中的对象的引用。
    2. 参数 2:是否允许查找场景对象。
    3. 参数 3:查找对象名称过滤(比如这里的 normal 是指文件名称中有 normal 的会被搜索到)。
    4. 参数 4:controlID,默认写 0。
  • 获取选择对象:EditorGUIUtility.GetObjectPickerObject()

​ 弹出的搜索窗口会通过发送事件的形式,通知开启它的窗口对象信息的变化,通过 Event 公共类获取其它窗口发送给自己的事件。

  • Event.current:获取当前事件。
  • commandName:获取事件命令的名字。
    • ObjectSelectorUpdated:对象选择发生变化时发送。
    • ObjectSelectorClosed:对象选择窗口关闭时发送。

书写形式:

if(Event.current.commandName == "ObjectSelectorUpdated") {
    // 选择发生更新时,通知进入
}
else if (Event.current.commandName == "ObjectSelectorClosed") {
    // 选择窗口关闭时,通知进入
}

3.2 PingObject

  • EditorGUIUtility.PingObject(想要提示选中的对象);

3.3 代码示例

public class Lesson12 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson12/EditorGUIUtility学习面板")]
    private static void OpenLesson12() {
        Lesson12 win = EditorWindow.GetWindow<Lesson12>("EditorGUIUtility学习面板");
        win.Show();
    }

    private Texture img3;

    private void OnGUI() {
        // 搜索框查询
        if (GUILayout.Button("打开搜索框查询窗口")) {
            EditorGUIUtility.ShowObjectPicker<Texture>(null, false, "Editor", 0);
        }

        if (Event.current.commandName == "ObjectSelectorUpdated") {
            img3 = EditorGUIUtility.GetObjectPickerObject() as Texture;
            if (img3 != null)
                Debug.Log(img3.name);
        }
        else if (Event.current.commandName == "ObjectSelectorClosed") {
            img3 = EditorGUIUtility.GetObjectPickerObject() as Texture;
            if (img3 != null)
                Debug.Log("窗口关闭 - " + img3.name);
        }

        // 对象选中提示提示
        if (GUILayout.Button("高亮选中对象")) {
            if (img3 != null)
                EditorGUIUtility.PingObject(img3);
        }
    }
}
image-20240213125311425 image-20240213125445836

4 窗口事件传递、坐标转换

4.1 CommandEvent

  • Event e = EditorGUIUtility.CommandEvent("事件名");

​ 获取到另一个窗口后,该窗口调用 SendEvent(e),在另一个窗口中通过

  • Event.current.type == EventType.ExecuteCommand 判断
  • Event.current.commandName == "事件名" 判断

​ 在传递事件时,Unity 会自动将接受事件的窗口打开,不管对象是否有监听处理对应的内容。

4.2 GUIPoint 和 ScreenPoint

  • 屏幕坐标系:原点为屏幕左上角。
  • GUI 坐标系:原点为当前窗口左上角。
  1. GUIToScreenPoint:将点从 GUI 位置转换为屏幕空间。
  2. GUIToScreenRect:将 rect 从 GUI 位置转换为屏幕空间。
  3. ScreenToGUIPoint:将点从屏幕空间转换为 GUI 位置。
  4. ScreenToGUIRect:将 rect 从屏幕空间转换为 GUI 位置。

4.3 代码示例

public class Lesson12 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson12/EditorGUIUtility学习面板")]
    private static void OpenLesson12() {
        Lesson12 win = EditorWindow.GetWindow<Lesson12>("EditorGUIUtility学习面板");
        win.Show();
    }

    private void OnGUI() {
        // 窗口事件传递
        if (GUILayout.Button("传递事件")) {
            // 声明事件
            Event   e   = EditorGUIUtility.CommandEvent("我的事件");
            Lesson3 win = EditorWindow.GetWindow<Lesson3>();
            win.SendEvent(e);
        }

        if (Event.current.type == EventType.ExecuteCommand) {
            if (Event.current.commandName == "我的事件") {
                Debug.Log("收到我的事件");
            }
        }

        // 坐标转换
        if (GUILayout.Button("坐标转换测试")) {
            Vector2 v = new Vector2(10, 10);
            GUI.BeginGroup(new Rect(10, 10, 100, 100));
            // 转换函数 如果包裹在布局相关函数中 那么位置胡加上布局的偏移 再进行转换
            Vector2 screenPos = EditorGUIUtility.GUIToScreenPoint(v);
            GUI.EndGroup();
            Debug.Log("GUI:" + v + "Screen:" + screenPos);
        }
    }
}
image-20240213130359689

5 指定区域使用对应鼠标指针

5.1 AddCursorRect

  • AddCursorRect(Rect position, MouseCursor mouse);
MouseCursor鼠标光标类型枚举
Arrow普通指针箭头
Text文本文本光标
ResizeVertical调整大小垂直调整大小箭头
ResizeHorizontal调整大小水平调整大小箭头
Link带有链接徽章的链接箭头
SlideArrow滑动箭头带有小箭头的箭头,用于指示在数字字段处滑动
ResizeUpRight调整大小向上向右调整窗口边缘的大小
ResizeUpLeft窗口边缘为左
MoveArrow带有移动符号的箭头旁边用于场景视图
RotateArrow旁边有用于场景视图的旋转符号
ScaleArrow旁边有用于场景视图的缩放符号
ArrowPlus旁边带有加号的箭头
ArrowMinus旁边带有减号的箭头
Pan用拖动的手拖动光标进行平移
Orbit用眼睛观察轨道的光标
Zoom使用放大镜进行缩放的光标
FPS带眼睛的光标和用于 FPS 导航的样式化箭头键
CustomCursor当前用户定义的光标
SplitResizeUpDown向上 - 向下调整窗口拆分器的大小箭头
SplitResizeLeftRight窗口拆分器的左 - 右调整大小箭头

6 绘制色板、绘制曲线

6.1 DrawColorSwatch

  • EditorGUIUtility.DrawColorSwatch(Rect 绘制色板的矩形, Color 颜色);

​ 在指定区域绘制一个色板矩形,主要配合 EditorGUILayout.ColorField 颜色输入控件使用。

6.2 DrawCurveSwatch

  • EditorGUIUtility.DrawCurveSwatch(Rect: 绘制曲线的范围, AnimationCurve: 曲线, SerializedProperty: 要绘制为SerializedProperty的曲线, Color: 绘制曲线的颜色, Color: 绘制背景的颜色);

​ 在指定区域绘制曲线,主要配合 EditorGUILayout.CurveField 曲线输入控件使用。

6.3 代码示例

public class Lesson12 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson12/EditorGUIUtility学习面板")]
    private static void OpenLesson12() {
        Lesson12 win = EditorWindow.GetWindow<Lesson12>("EditorGUIUtility学习面板");
        win.Show();
    }

    private Color color;
    private AnimationCurve curve = new AnimationCurve();

    private void OnGUI() {
        // 绘制色板
        color = EditorGUILayout.ColorField(new GUIContent("选取颜色"), color, true, true, true);
        EditorGUIUtility.DrawColorSwatch(new Rect(180, 180, 30, 30), Color.blue);

        // 绘制曲线
        curve = EditorGUILayout.CurveField("曲线设置", curve);
        EditorGUIUtility.DrawCurveSwatch(new Rect(0, 300, 100, 80), curve, null, Color.red, Color.white);
    }
}
image-20240213131412472

6.4 更多 API

​ 官方文档:https://docs.unity3d.com/ScriptReference/EditorGUIUtility.html。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1447423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于在分布式环境中RVN和使用场景的介绍3

简介 在《关于在分布式环境中RVN和使用场景的介绍2》和《关于在分布式环境中RVN和使用场景的介绍1》中我们介绍了RVN的概念和在一些具体用例中的使用。在本文中我们讨论一下在分布式环境中使用RVN需要注意的问题。 问题 我们在收到一条待处理的事件时&#xff0c;需要检查该…

代码随想录算法训练营Day56|583. 两个字符串的删除操作、72. 编辑距离

目录 583. 两个字符串的删除操作 前言 思路 算法实现 法二 72. 编辑距离 前言 思路 算法实现 总结 583. 两个字符串的删除操作 题目链接 文章链接 前言 本题与上一题不同的子序列相比&#xff0c;变化就是两个字符串都可以进行删除操作了。 思路 利用动规五部曲进…

Ocr之TesseractOcr的安装及使用

目录 一、安装环境 二、安装内容 三、安装过程及识别测试 1. 安装过程 2. 程序编写 总结 1. 安装复杂度较低 2. 国外开源Ocr 3. 可设置识别参数 4. 工具类 一、 系统环境windows 10 linux环境也可安装, 可借鉴此篇文章>> | 二、安装内容 Tesseract exe 程序安…

《金融人工智能:用python实现ai量化交易》

融合了数学、python、深度学习以及金融知识&#xff0c;是本推荐的好书。请收藏本文&#xff0c;读后再给大学总结。

React18原理: 核心包结构与两大工作循环

React核心包结构 1 ) react react基础包&#xff0c;只提供定义 react组件(ReactElement)的必要函数一般来说需要和渲染器(react-dom,react-native)一同使用在编写react应用的代码时, 大部分都是调用此包的api比如, 我们定义组件的时候&#xff0c;就是它提供的class Demo ext…

Elasticsearch:适用于 iOS 和 Android 本机应用程序的 Elastic APM

作者&#xff1a;来自 Elastic Akhilesh Pokhariyal, Cesar Munoz, Bryce Buchanan 适用于本机应用程序的 Elastic APM 提供传出 HTTP 请求和视图加载的自动检测&#xff0c;捕获自定义事件、错误和崩溃&#xff0c;并包括用于数据分析和故障排除目的的预构建仪表板。 适用于 …

LeetCode:83和82.删除排序链表中的重复元素I,II

这两题算是链表的基础题&#xff0c;就遍历删除没啥特点&#xff0c; 83甚至不需要考虑第一个结点的特殊情况&#xff0c;属实是名副其实的easy了 LeetCode&#xff1a;21.合并两个有序链表之第一次的特殊情况-CSDN博客 83. 删除排序链表中的重复元素 - 力扣&#xff08;Lee…

[NSSCTF]-Web:[SWPUCTF 2021 新生赛]easyrce解析

先看网页 代码审计&#xff1a; error_reporting(0); &#xff1a;关闭报错&#xff0c;代码的错误将不会显示 highlight_file(__FILE__); &#xff1a;将当前文件的源代码显示出来 eval($_GET[url]); &#xff1a;将url的值作为php代码执行 解题&#xff1a; 题目既然允许…

备战蓝桥杯---动态规划(入门1)

先补充一下背包问题&#xff1a; 于是&#xff0c;我们把每一组当成一个物品&#xff0c;f[k][v]表示前k组花费v的最大值。 转移方程还是max(f[k-1][v],f[k-1][v-c[i]]w[i]) 伪代码&#xff08;注意循环顺序&#xff09;&#xff1a; for 所有组&#xff1a; for vmax.....0…

wayland(xdg_wm_base) + egl + opengles 纹理贴图进阶实例(四)

文章目录 前言一、使用gstreamer 获取 pattern 图片二、代码实例1. pattern 图片作为纹理数据源的代码实例1.1 基于opengles2.0 接口的 egl_wayland_texture2_1.c1.2 基于opengles3.0 接口的 egl_wayland_texture3_1.c2. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c3…

算法学习——LeetCode力扣二叉树篇8

算法学习——LeetCode力扣二叉树篇8 669. 修剪二叉搜索树 669. 修剪二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 描述 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high…

Day 44 | 动态规划 完全背包、518. 零钱兑换 II 、 377. 组合总和 Ⅳ

完全背包 题目 文章讲解 视频讲解 完全背包和0-1背包的区别在于&#xff1a;物品是否可以重复使用 思路&#xff1a;对于完全背包问题&#xff0c;内层循环的遍历方式应该是从weight[i]开始一直遍历到V&#xff0c;而不是从V到weight[i]。这样可以确保每种物品可以被选择多次…

解决Thymeleaf的地震震中距离展示[[]]双引号报错的问题

目录 前言 一、问题场景还原 1、需求场景 2、系统设计 3、功能实现 4、线数据标注展示 5、页面出错 二、解决Thymeleaf报错 1、错误说明 2、参数改造 3、问题修复 总结 前言 今天是2024年2月12日&#xff0c;农历正月初三&#xff0c;还是农历龙年春节。在这里首先…

ubuntu快速安装miniconda

ubuntu快速安装miniconda 环境 ubuntu.22.04 显卡 RTX 3050 关于选择Miniconda还是Anaconda的问题&#xff0c;Anaconda安装包比较大&#xff0c;耗时比较长&#xff0c;如果你是绝对的初学者&#xff0c;选择Anaconda会比较稳妥一些&#xff1b;否则建议你还是选择Miniconda安…

docker 1:介绍

docker 1&#xff1a;介绍 docker解决哪些问题&#xff1a; 传统APP在安装到不同电脑的时候可能会遇到依赖问题&#xff0c;比如缺少VS 20xx&#xff0c;软件无法运行”的情况。docker使用容器技术将软件 依赖​打包为image包发布&#xff0c;解决了依赖问题。docker有一个官…

考研高数(导数的定义)

总结&#xff1a; 导数的本质就是极限。 函数在某点可导就必连续&#xff0c;连续就有极限且等于该点的函数值。 例题1&#xff1a;&#xff08;归结原则的条件是函数可导&#xff09; 例题2&#xff1a; 例题3&#xff1a;

Unity下使用Sqlite

sqlite和access类似是文件形式的数据库&#xff0c;不需要安装任何服务&#xff0c;可以存储数据&#xff0c;使用起来还是挺方便的。 首先需要安装DLL 需要的DLL 我们找到下面两个文件放入Plugins目录 Mono.Data.Sqlite.dll System.Data.dll DLL文件位于Unity的安装目录下的…

controller-manager学习三部曲之三:deployment的controller启动分析

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 《controller-manager学习三部曲》完整链接 通过脚本文件寻找程序入口源码学习deployment的controller启动分析 本篇概览 本文是《controller-manager学习三…

部署JForum2过程。

居然用了两天时间&#xff0c;才把JForum2部署成功。走了一些弯路&#xff0c;主要原因是想当然&#xff0c;以为jdk和tomcat&#xff0c;应该向下兼容&#xff0c;所以就随便选的版本。 一、jdk-17、apache-tomcat-10.1.18-windows-x64&#xff0c;部署完jforum-2.8.2.war,改…

基于STM32与FreeRTOS的四轴机械臂项目

目录 一、项目介绍 二、前期准备 1.硬件准备 2.开发环境 3.CubeMX配置 三、裸机各种模块测试 1.舵机模块 2.蓝牙模块 3.按键摇杆传感器模块和旋钮电位器模块 4.OLED模块 5.W25Q128模块 四、裸机三种控制测试 1.摇杆控制 2.示教器控制 3.蓝牙控制 五、裸机与Free…