2024-02-12 Unity 编辑器开发之编辑器拓展3 —— EditorGUI

文章目录

  • [1 GUILayout](#1 GUILayout)
  • [2 EditorGUI 介绍](#2 EditorGUI 介绍)
  • [3 文本、层级、标签、颜色拾取](#3 文本、层级、标签、颜色拾取)
    • [3.1 LabelField](#3.1 LabelField)
    • [3.2 LayerField](#3.2 LayerField)
    • [3.3 TagField](#3.3 TagField)
    • [3.4 ColorField](#3.4 ColorField)
    • [3.5 代码示例](#3.5 代码示例)
  • [4 枚举选择、整数选择、按下按钮](#4 枚举选择、整数选择、按下按钮)
    • [4.1 EnumPopup / EnumFlagsField](#4.1 EnumPopup / EnumFlagsField)
    • [4.2 IntPopup](#4.2 IntPopup)
    • [4.3 DropdownButton](#4.3 DropdownButton)
    • [4.4 代码示例](#4.4 代码示例)
  • [5 对象关联、各类型输入](#5 对象关联、各类型输入)
    • [5.1 ObjectField](#5.1 ObjectField)
    • [5.2 各类型输入](#5.2 各类型输入)
    • [5.3 代码示例](#5.3 代码示例)
  • [6 折叠、折叠组](#6 折叠、折叠组)
    • [6.1 Foldout](#6.1 Foldout)
    • [6.2 BeginFoldoutHeaderGroup / EndFoldoutHeaderGroup](#6.2 BeginFoldoutHeaderGroup / EndFoldoutHeaderGroup)
    • [6.3 代码示例](#6.3 代码示例)
  • [7 开关、开关组](#7 开关、开关组)
    • [7.1 Toggle / ToggleLeft](#7.1 Toggle / ToggleLeft)
    • [7.2 BeginToggleGroup / EndToggleGroup](#7.2 BeginToggleGroup / EndToggleGroup)
    • [7.3 代码示例](#7.3 代码示例)
  • [8 滑动条、双滑块滑动条](#8 滑动条、双滑块滑动条)
    • [8.1 Slider / IntSlider](#8.1 Slider / IntSlider)
    • [8.2 MinMaxSlider](#8.2 MinMaxSlider)
    • [8.3 代码示例](#8.3 代码示例)
  • [9 帮助框、间隔](#9 帮助框、间隔)
    • [9.1 HelpBox](#9.1 HelpBox)
    • [9.2 Space](#9.2 Space)
    • [9.3 代码示例](#9.3 代码示例)
  • [10 动画曲线、布局](#10 动画曲线、布局)
    • [10.1 CurveField](#10.1 CurveField)
    • [10.2 布局相关 API](#10.2 布局相关 API)
    • [10.3 代码示例](#10.3 代码示例)

1 GUILayout

​ GUILayout 是 GUI 自动布局的公共类,其中的方法和 GUI 基本类似,均用来绘制、响应各种 UI 控件,不同之处在于 GUILayout 在 GUI 的基础上加入了自动布局功能,无需过多关心 UI 控件的位置和大小。

GUILayoutOption 布局选项

  1. 控件的固定宽高
    • GUILayout.Width(300);
    • GUILayout.Height(200);
  2. 允许控件的最小宽高
    • GUILayout.MinWidth(50);
    • GUILayout.MinHeight(50);
  3. 允许控件的最大宽高
    • GUILayout.MaxWidth(100);
    • GUILayout.MaxHeight(100);
  4. 允许或禁止水平拓展
    • GUILayout.ExpandWidth(true); //允许
    • GUILayout.ExpandHeight(false); //禁止
    • GUILayout.ExpandHeight(true); //允许
    • GUILayout.ExpandHeight(false); //禁止

2 EditorGUI 介绍

​ EditorGUI 类似 GUI,是用于绘制编辑器拓展 UI 的工具类,提供 GUI 中没有的 API(主要是编辑器功能中会用到的一些特殊控件)。

​ EditorGUILayout 类似于 GUILayout,是带有自动布局功能的 EditorGUI 绘制工具类。通常,会将 EditorGUI 和 GUI 混合使用来制作编辑器拓展功能。但由于用到自动布局功能,因此接下来着重介绍 EditorGUILayout 中的功能。EditorGUI 和它的区别仅仅是需要自己设置位置而已。

​ 详细内容:https://docs.unity.cn/cn/2022.3/ScriptReference/EditorGUILayout.html。

3 文本、层级、标签、颜色拾取

3.1 LabelField

  • EditorGUILayout.LabelField("文本标题", "文本内容");

3.2 LayerField

  • int变量 = EditorGUILayout.LayerField("层级选择", int变量);

3.3 TagField

  • string变量 = EditorGUILayout.TagField("标签选择", string变量);

3.4 ColorField

  • color变量 = EditorGUILayout.ColorField(new GUIContent("标题"), color变量, 是否显示拾色器, 是否显示透明度通道, 是否支持HDR);

3.5 代码示例

csharp 复制代码
public class Lesson3 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson3/EditorGUI知识讲解窗口")]
    private static void OpenLesson3() {
        Lesson3 win = EditorWindow.GetWindow<Lesson3>("EditorGUI知识讲解窗口");
        win.Show();
    }

    int    layer;
    string tag;
    Color  color;

    private void OnGUI() {
        // 窗口中的控件相关绘制 逻辑处理相关的内容
        // EditorGUI相关的控件 同样还是需要在OnGUI当中进行实现 才能被显示出来

        // 文本
        EditorGUILayout.LabelField("文本标题", "测试内容");
        EditorGUILayout.LabelField("文本内容");
        
        // 层级
        layer = EditorGUILayout.LayerField("层级选择", layer);
        
        // 标签
        tag = EditorGUILayout.TagField("标签选择", tag);
        
        // 颜色获取
        color = EditorGUILayout.ColorField(new GUIContent("自定义颜色获取"), color, true, false, false);
    }
}

4 枚举选择、整数选择、按下按钮

4.1 EnumPopup / EnumFlagsField

  • 枚举选择

    枚举变量 = (枚举类型)EditorGUILayout.EnumPopup("枚举选择", 枚举变量);

  • 多选枚举

    注意:多选枚举进行的是或运算,声明枚举时一定注意其中的赋值,并且一定要有多种情况的搭配值。

    枚举变量 = (枚举类型)EditorGUILayout.EnumFlagsField("枚举多选", 枚举变量);

4.2 IntPopup

  • int变量 = EditorGUILayout.IntPopup("整数单选框", int变量, 字符串数组, int数组);
  • EditorGUILayout.DropdownButton(new GUIContent("按钮上文字"), FocusType.Passive)
    • FocusType:枚举时告诉 UI 系统能够获得键盘焦点,当用户按 Tab 键时在控件之间进行切换。
    • Keyboard:该控件可接收键盘焦点。
    • Passive:该控件不能接收键盘焦点。

4.4 代码示例

csharp 复制代码
public enum E_TestType
{
    One         = 1,
    Two         = 2,
    Three       = 4,
    One_and_Two = 1 | 2,
}

public class Lesson3 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson3/EditorGUI知识讲解窗口")]
    private static void OpenLesson3() {
        Lesson3 win = EditorWindow.GetWindow<Lesson3>("EditorGUI知识讲解窗口");
        win.Show();
    }

    E_TestType type;
    E_TestType type2;

    string[] strs = { "选择123", "选择234", "选择345" };
    int[]    ints = { 123, 234, 345 };
    int      num  = 0;

    private void OnGUI() {
        // 枚举选择
        type = (E_TestType)EditorGUILayout.EnumPopup("枚举选择", type);

        type2 = (E_TestType)EditorGUILayout.EnumFlagsField("枚举多选", type2);

        // 整数选择控件
        // 返回值是整数数组当中的某一个值
        num = EditorGUILayout.IntPopup("整数单选框", num, strs, ints);
        EditorGUILayout.LabelField(num.ToString());

        // 按下就响应的按钮
        if (EditorGUILayout.DropdownButton(new GUIContent("按钮上文字"), FocusType.Passive))
            Debug.Log("按下就响应");
    }
}

5 对象关联、各类型输入

5.1 ObjectField

  • 对象变量 = EditorGUILayout.ObjectField(对象变量, typeof(对象类型), 是否允许关联场景上对象资源) as 对象类型;

5.2 各类型输入

  • int变量 = EditorGUILayout.IntField("Int输入框", int变量);

  • long变量 = EditorGUILayout.LongField("long输入框", long变量);

  • float变量 = EditorGUILayout.FloatField("Float 输入:", float变量);

  • double变量 = EditorGUILayout.DoubleField("double 输入:", double变量);

  • string变量 = EditorGUILayout.TextField("Text输入:", string变量);

  • vector2变量 = EditorGUILayout.Vector2Field("Vec2输入: ", vector2变量);

  • vector3变量 = EditorGUILayout.Vector3Field("Vec3输入: ", vector3变量);

  • vector4变量 = EditorGUILayout.Vector4Field("Vec4输入: ", vector4变量);

  • rect变量 = EditorGUILayout.RectField("rect输入: ", rect变量);

  • bounds变量 = EditorGUILayout.BoundsField("Bounds输入: ", bounds变量);

  • boundsInt变量 = EditorGUILayout.BoundsIntField("Bounds输入: ", boundsInt变量);

​ 注意:EditorGUILayout 中 Delayed 开头的输入控件和普通输入控件最主要的区别是:在用户按 Enter 键或将焦点从字段移开之前,返回值不会更改。

5.3 代码示例

csharp 复制代码
public class Lesson3 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson3/EditorGUI知识讲解窗口")]
    private static void OpenLesson3() {
        Lesson3 win = EditorWindow.GetWindow<Lesson3>("EditorGUI知识讲解窗口");
        win.Show();
    }

    GameObject obj;

    int    i;
    int    i2;
    float  f;
    double d;
    long   l;

    string  str;
    Vector2 vec2;
    Vector3 vec3;
    Vector4 vec4;

    Rect      rect;
    Bounds    bounds;
    BoundsInt boundsInt;

    private void OnGUI() {
        // 对象关联
        obj = EditorGUILayout.ObjectField("关联资源对象", obj, typeof(GameObject), false) as GameObject;
        // 各类型输入
        i = EditorGUILayout.IntField("Int输入框", i);
        EditorGUILayout.LabelField(i.ToString());
        l = EditorGUILayout.LongField("long输入框", l);
        f = EditorGUILayout.FloatField("Float 输入:", f);
        d = EditorGUILayout.DoubleField("double 输入:", d);

        str = EditorGUILayout.TextField("Text输入:", str);
        vec2 = EditorGUILayout.Vector2Field("Vec2输入: ", vec2);
        vec3 = EditorGUILayout.Vector3Field("Vec3输入: ", vec3);
        vec4 = EditorGUILayout.Vector4Field("Vec4输入: ", vec4);

        rect = EditorGUILayout.RectField("rect输入: ", rect);
        bounds = EditorGUILayout.BoundsField("Bounds输入: ", bounds);
        boundsInt = EditorGUILayout.BoundsIntField("Bounds输入: ", boundsInt);

        // 注意:EditorGUILayout 中 Delayed 开头的输入控件和普通输入控件最主要的区别是:
        //      在用户按 Enter 键或将焦点从字段移开之前,返回值不会更改。
        i2 = EditorGUILayout.DelayedIntField("Int输入框", i2);
        EditorGUILayout.LabelField(i2.ToString());
    }
}

6 折叠、折叠组

6.1 Foldout

  • bool变量 = EditorGUILayout.Foldout(bool变量, "标题名");

6.2 BeginFoldoutHeaderGroup / EndFoldoutHeaderGroup

  • bool变量 = EditorGUILayout.BeginFoldoutHeaderGroup(bool变量, "标题名");

    ...

    EditorGUILayout.EndFoldoutHeaderGroup();

​ 折叠组会有高亮加粗的显示,而普通折叠没有。

6.3 代码示例

csharp 复制代码
public enum E_TestType
{
    One         = 1,
    Two         = 2,
    Three       = 4,
    One_and_Two = 1 | 2,
}

public class Lesson3 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson3/EditorGUI知识讲解窗口")]
    private static void OpenLesson3() {
        Lesson3 win = EditorWindow.GetWindow<Lesson3>("EditorGUI知识讲解窗口");
        win.Show();
    }


    E_TestType type;
    E_TestType type2;

    string[] strs = { "选择123", "选择234", "选择345" };
    int[]    ints = { 123, 234, 345 };
    int      num  = 0;

    GameObject obj;

    int    i;
    int    i2;
    float  f;
    double d;
    long   l;

    string  str;
    Vector2 vec2;
    Vector3 vec3;
    Vector4 vec4;

    Rect      rect;
    Bounds    bounds;
    BoundsInt boundsInt;

    bool isHide;
    bool isHideGroup;

    private void OnGUI() {
        isHide = EditorGUILayout.Foldout(isHide, "折叠控件", false);

        if (isHide) {
            // 枚举选择
            type = (E_TestType)EditorGUILayout.EnumPopup("枚举选择", type);

            type2 = (E_TestType)EditorGUILayout.EnumFlagsField("枚举多选", type2);

            // 整数选择控件
            // 返回值是整数数组当中的某一个值
            num = EditorGUILayout.IntPopup("整数单选框", num, strs, ints);
            EditorGUILayout.LabelField(num.ToString());

            // 按下就响应的按钮
            if (EditorGUILayout.DropdownButton(new GUIContent("按钮上文字"), FocusType.Passive))
                Debug.Log("按下就响应");
        }

        isHideGroup = EditorGUILayout.BeginFoldoutHeaderGroup(isHideGroup, "折叠组控件");

        if (isHideGroup) {
            // 对象关联
            obj = EditorGUILayout.ObjectField("关联资源对象", obj, typeof(GameObject), false) as GameObject;
            // 各类型输入
            i = EditorGUILayout.IntField("Int输入框", i);
            EditorGUILayout.LabelField(i.ToString());
            l = EditorGUILayout.LongField("long输入框", l);
            f = EditorGUILayout.FloatField("Float 输入:", f);
            d = EditorGUILayout.DoubleField("double 输入:", d);

            str = EditorGUILayout.TextField("Text输入:", str);
            vec2 = EditorGUILayout.Vector2Field("Vec2输入: ", vec2);
            vec3 = EditorGUILayout.Vector3Field("Vec3输入: ", vec3);
            vec4 = EditorGUILayout.Vector4Field("Vec4输入: ", vec4);

            rect = EditorGUILayout.RectField("rect输入: ", rect);
            bounds = EditorGUILayout.BoundsField("Bounds输入: ", bounds);
            boundsInt = EditorGUILayout.BoundsIntField("Bounds输入: ", boundsInt);

            // 注意:EditorGUILayout 中 Delayed 开头的输入控件和普通输入控件最主要的区别是:
            //      在用户按 Enter 键或将焦点从字段移开之前,返回值不会更改。
            i2 = EditorGUILayout.DelayedIntField("Int输入框", i2);
            EditorGUILayout.LabelField(i2.ToString());
        }

        EditorGUILayout.EndFoldoutHeaderGroup();
    }
}

7 开关、开关组

7.1 Toggle / ToggleLeft

  • 普通开关

    bool变量 = EditorGUILayout.Toggle("普通开关", bool变量);

  • 左侧开关

    bool变量 = EditorGUILayout.ToggleLeft("开关在左侧", bool变量);

7.2 BeginToggleGroup / EndToggleGroup

  • bool变量 = EditorGUILayout.BeginToggleGroup("开关组", bool变量);

    ...

    EditorGUILayout.EndToggleGroup();

7.3 代码示例

csharp 复制代码
public class Lesson3 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson3/EditorGUI知识讲解窗口")]
    private static void OpenLesson3() {
        Lesson3 win = EditorWindow.GetWindow<Lesson3>("EditorGUI知识讲解窗口");
        win.Show();
    }

    bool isTog;
    bool isTogLeft;

    bool isTogGroup;

    private void OnGUI() {
        // 开关组控件
        isTogGroup = EditorGUILayout.BeginToggleGroup("开关组控件", isTogGroup);
        
        // 开关控件
        isTog = EditorGUILayout.Toggle("开关控件", isTog);
        isTogLeft = EditorGUILayout.ToggleLeft("左侧开关", isTogLeft);
        EditorGUILayout.EndToggleGroup();
    }
}

8 滑动条、双滑块滑动条

8.1 Slider / IntSlider

  • float变量 = EditorGUILayout.Slider("滑动条", float变量, 最小值, 最大值);
  • int变量 = EditorGUILayout.IntSlider("整数值滑动条", int变量, 最小值, 最大值);

8.2 MinMaxSlider

  • EditorGUILayout.MinMaxSlider("双块滑动条", ref 左侧值, ref 右侧值, 最小值, 最大值);

​ 没有返回值,通过 ref 关键字修改数值。

8.3 代码示例

csharp 复制代码
public class Lesson3 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson3/EditorGUI知识讲解窗口")]
    private static void OpenLesson3() {
        Lesson3 win = EditorWindow.GetWindow<Lesson3>("EditorGUI知识讲解窗口");
        win.Show();
    }

    float fSlider;
    int   iSlider;

    float leftV;
    float rightV;

    private void OnGUI() {
        // 滑动条
        fSlider = EditorGUILayout.Slider("滑动条", fSlider, 0, 10);
        iSlider = EditorGUILayout.IntSlider("整形滑动条", iSlider, 0, 10);
        
        // 双块滑动条
        EditorGUILayout.MinMaxSlider("双块滑动条", ref leftV, ref rightV, 0, 10);
        EditorGUILayout.LabelField(leftV.ToString());
        EditorGUILayout.LabelField(rightV.ToString());
    }
}

9 帮助框、间隔

9.1 HelpBox

  • EditorGUILayout.HelpBox("一般提示", MessageType.None);
  • EditorGUILayout.HelpBox("感叹号提示", MessageType.Info);
  • EditorGUILayout.HelpBox("警告符号提示", MessageType.Warning);
  • EditorGUILayout.HelpBox("错误符号提示", MessageType.Error);

9.2 Space

  • EditorGUILayout.Space(10); // 间隔 10 个单位

9.3 代码示例

csharp 复制代码
public class Lesson3 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson3/EditorGUI知识讲解窗口")]
    private static void OpenLesson3() {
        Lesson3 win = EditorWindow.GetWindow<Lesson3>("EditorGUI知识讲解窗口");
        win.Show();
    }

    private void OnGUI() {
        EditorGUILayout.HelpBox("一般提示", MessageType.None);
        EditorGUILayout.Space(10);
        EditorGUILayout.HelpBox("感叹号提示", MessageType.Info);
        EditorGUILayout.Space(50);
        EditorGUILayout.HelpBox("警告符号提示", MessageType.Warning);
        EditorGUILayout.Space(100);
        EditorGUILayout.HelpBox("错误符号提示", MessageType.Error);
    }
}

10 动画曲线、布局

10.1 CurveField

  • AnimationCurve变量 = EditorGUILayout.CurveField("动画曲线:", AnimationCurve变量);

10.2 布局相关 API

  • 水平布局

    EditorGUILayout.BeginHorizontal(); // 开始水平布局

    ...
    EditorGUILayout.EndHorizontal(); // 结束水平布局

  • 垂直布局

    EditorGUILayout.BeginVertical(); // 开始垂直布局
    ...
    EditorGUILayout.EndVertical(); // 结束垂直布局

  • 滚动视图

    Vector2布局 = EditorGUILayout.BeginScrollView(Vector2布局); // 开启滚动视图

    ...
    EditorGUILayout.EndScrollView(); // 结束滚动视图

10.3 代码示例

csharp 复制代码
public class Lesson3 : EditorWindow
{
    [MenuItem("Unity编辑器拓展/Lesson3/EditorGUI知识讲解窗口")]
    private static void OpenLesson3() {
        Lesson3 win = EditorWindow.GetWindow<Lesson3>("EditorGUI知识讲解窗口");
        win.Show();
    }

    bool isTog;
    bool isTogLeft;

    bool isTogGroup;

    float fSlider;
    int   iSlider;

    float leftV;
    float rightV;

    AnimationCurve curve = new AnimationCurve();

    Vector2 vec2Pos;

    private void OnGUI() {
        vec2Pos = EditorGUILayout.BeginScrollView(vec2Pos); // 开启滚动视图

        // 开关组控件
        isTogGroup = EditorGUILayout.BeginToggleGroup("开关组控件", isTogGroup);
        // 开关控件
        isTog = EditorGUILayout.Toggle("开关控件", isTog);
        isTogLeft = EditorGUILayout.ToggleLeft("左侧开关", isTogLeft);
        EditorGUILayout.EndToggleGroup();

        // 滑动条
        fSlider = EditorGUILayout.Slider("滑动条", fSlider, 0, 10);
        iSlider = EditorGUILayout.IntSlider("整形滑动条", iSlider, 0, 10);
        // 双块滑动条
        EditorGUILayout.MinMaxSlider("双块滑动条", ref leftV, ref rightV, 0, 10);
        EditorGUILayout.LabelField(leftV.ToString());
        EditorGUILayout.LabelField(rightV.ToString());

        // 帮助框控件
        EditorGUILayout.HelpBox("一般提示", MessageType.None);
        EditorGUILayout.Space(10);
        EditorGUILayout.HelpBox("感叹号提示", MessageType.Info);
        EditorGUILayout.Space(50);
        EditorGUILayout.HelpBox("警告符号提示", MessageType.Warning);
        EditorGUILayout.Space(100);
        EditorGUILayout.HelpBox("错误符号提示", MessageType.Error);
        // 间隔控件

        EditorGUILayout.EndScrollView(); // 结束滚动视图

        // 动画曲线控件
        curve = EditorGUILayout.CurveField("曲线控件", curve);
        // 布局API
        EditorGUILayout.BeginHorizontal(); // 开始水平布局
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.EndHorizontal(); // 结束水平布局

        EditorGUILayout.BeginVertical(); // 开始垂直布局
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.EndVertical(); // 结束垂直布局
    }
}
相关推荐
kylezhao201915 小时前
C#winform数据绑定
c#
爱吃西红柿鸡蛋面18 小时前
JsonHelper使用
c#
故事不长丨18 小时前
C#线程编程全解析:从基础应用到高级实践
c#·线程·多线程·thread·线程同步·异步编程·线程锁
xiaowu0801 天前
C#调用 C++ DLL 加载地址方式选择
开发语言·c++·c#
孟无岐1 天前
【Laya】Laya 类使用说明
typescript·游戏引擎·游戏程序·laya
在路上看风景1 天前
1.2 Unity资源分类
unity·游戏引擎
one named slash1 天前
BMFont在Unity中生成艺术字
unity·游戏引擎
微醺的老虎1 天前
【工具】vscode格式化json文件
ide·vscode·编辑器
乔宕一1 天前
vscode 设置每次调试 powershell 脚本都使用临时的 powershell 终端
ide·vscode·编辑器
码农学院1 天前
使用腾讯翻译文本
服务器·数据库·c#