IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity编辑器拓展PropertyDrawer——Editor绘制偷懒神器 -> 正文阅读

[游戏开发]Unity编辑器拓展PropertyDrawer——Editor绘制偷懒神器

写在前面

我们在使用UnityEditor自定义属性面板时,大多的时候都是直接使用继承Editor的方式实现,一个脚本类写一个Editor类,但是有很多非MonoBehaviour的类,会需要在不同的脚本上使用,这个时候需求就来了,每一个都要重复写那也太麻烦了,这个时候就可以用PropertyDrawer了。

我使用的Unity版本:Unity 2020.3.10
在这里插入图片描述

总结

PropertyDrawer的两大主要作用:
1. 用于自定义绘制可序列化的类或结构体
有需要自定义显示的又会可能在多个脚本中使用到的类或结构体都可以使用PropertyDrawer来实现,PropertyDrawer如其名,就像一个专门的属性绘制器一样,对一个类或结构体进行自定义属性绘制后,当脚本在属性面板上显示该属性时,就会调用到该自定义的绘制,不用我们再写Editor脚本去单独绘制,所以省去了大量的工作
2. 搭配PropertyAttribute可自定义Attribute
相信大家平常都有用过诸如【Header】【ToolTip】之类的Attribute,而通过PropertyAttribute+PropertyDrawer就可以自定义自己的Attribute

自定义绘制可序列化的类或结构体

这里我们使用书,书单的类来示例这个功能
Book就是我们要进行自定义绘制的类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum BookType
{
    Novel,
    Science,
    Life,
    Tool,
}
[System.Serializable]
public class Book
{
    public string name;
    public BookType type;
    public string overview;
}
public class BookList : MonoBehaviour
{
    public Book currentRead;
    public Book[] readList;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(Book))]
public class BookDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginProperty(position, label, property);
        //FocusType.Passive 使用Tab键切换时不会被选中,FocusType.Keyboard 使用Tab键切换时会被选中,很显然这里我们不需要label能被选中进行编辑 
        position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
        //不让indentLevel层级影响到同一行的绘制,因为PropertyDrawer在很多地方都有可能被用到,可能出现嵌套使用
        var indent = EditorGUI.indentLevel;
        EditorGUI.indentLevel = 0;
        var nameRect = new Rect(position.x, position.y, 50, position.height);
        var typeRect = new Rect(position.x + 55, position.y, 60, position.height);
        var overviewRect = new Rect(position.x + 120, position.y, position.width - 90, position.height);
        EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none);
        EditorGUI.PropertyField(typeRect, property.FindPropertyRelative("type"), GUIContent.none);
        EditorGUI.PropertyField(overviewRect, property.FindPropertyRelative("overview"), GUIContent.none);
        EditorGUI.indentLevel = indent;
        EditorGUI.EndProperty();
    }
}

自定义前后对比
在这里插入图片描述
后来我们又有一个书库的类,这个时候就不用再写Editor类了,直接就有效果

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class BookTypeList
{
    public string name;
    public Book[] bookList;
}
public class BookLibrary : MonoBehaviour
{
    [SerializeField]
    public List<BookTypeList> library;
}

在这里插入图片描述

PropertyAttribute+PropertyDrawer自定义Attribute

自定义Attribute可以让我们定义很多非常方便的Attribute去使用,我们这里实现一个Label的Attribute,经常策划会抱怨看不懂脚本上的参数,有了LabelAttribute,汉化工作就方便太多了
大家可以根据自己的需要大胆发挥创作
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LabelAttribute : PropertyAttribute
{
    public string name;
    public LabelAttribute(string name)
    {
        this.name = name;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(LabelAttribute))]
public class LabelAttributeDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        LabelAttribute labelAttribute = this.attribute as LabelAttribute;
        EditorGUI.PropertyField(position, property, new GUIContent(labelAttribute.name));
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LabelAttributeTest : MonoBehaviour
{
    [LabelAttribute("书籍名称")]
    public string bookName;
    [LabelAttribute("书籍类型")]
    public BookType bookType;
    [LabelAttribute("书籍价格")]
    public float price;
}

还未搞明白的

PropertyDrawer还有一个可重写的方法 CreatePropertyGUI,但不知如何用,具体用在哪里?目前还没有使用到,后续碰到再看,目前根据官方文档还是搞不明白。

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomPropertyDrawer(typeof(Book))]
public class BookDrawerUIE : PropertyDrawer
{
    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        var container = new VisualElement();
        var nameField = new PropertyField(property.FindPropertyRelative("name"));
        var typeField = new PropertyField(property.FindPropertyRelative("type"));
        var overviewField = new PropertyField(property.FindPropertyRelative("overview"));
        container.Add(nameField);
        container.Add(typeField);
        container.Add(overviewField);
        return container;
    }
}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-08 12:05:58  更:2021-10-08 12:06:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 2:40:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码