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

文章目录

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

csharp 复制代码
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);
    }
}

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:对象选择窗口关闭时发送。

书写形式:

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

3.2 PingObject

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

3.3 代码示例

csharp 复制代码
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);
        }
    }
}

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 代码示例

csharp 复制代码
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);
        }
    }
}

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 代码示例

csharp 复制代码
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);
    }
}

6.4 更多 API

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

相关推荐
呆呆小雅1 小时前
C#关键字volatile
java·redis·c#
乐闻x1 小时前
VSCode 插件开发实战(五):实现新语言支持和语法高亮
ide·vscode·编辑器
boligongzhu1 小时前
DALSA工业相机SDK二次开发(图像采集及保存)C#版
开发语言·c#·dalsa
web147862107231 小时前
C# .Net Web 路由相关配置
前端·c#·.net
乐闻x1 小时前
VSCode 插件开发实战(六):配置自定义状态栏
ide·vscode·编辑器
张明奇-琦玉1 小时前
vscode添加全局宏定义
ide·vscode·编辑器
星星不说话~1 小时前
VScode在远程服务器上安装Anaconda并确认安装成功的步骤
ide·vscode·编辑器
Jasmine_llq2 小时前
《 火星人 》
算法·青少年编程·c#
军训猫猫头4 小时前
20.抽卡只有金,带保底(WPF) C#
ui·c#·wpf
异次元的归来11 小时前
Unity DOTS中的share component
unity·游戏引擎