编辑器扩展基础3-自定义PropertyDrawer

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编辑器扩展基础3-自定义PropertyDrawer相关的知识,希望对你有一定的参考价值。

参考技术A

自定义Unity组件时如果不加以控制,会按照Unity默认的方式来排布显示可序列化属性。

如果我们向让属性显示得更个性化一些,可以自定义PropertyDrawer。

这个PropertyDrawer它可以指定Serializable类(可序列化类)或PropertyAttribute( 自定义属性 ),这样就有了两种使用:

另注
组件为什么能显示在Inspector面板上?
因为组件都继承自Monobehaviour,父类的initiate方法起到了序列化和反序列化的作用。这样就能保存为MetaData,供下次使用。

Serializable类(可序列化类)在Unity中有什么含义呢?
默认地,Unity只给自定义的公有变量、继承自MonoBehaviour的类执行序列化,所以如果想让一个类序列化,那么就要指定[Serializable]标签。它将MetaData放入可以通过反射重新获取并由Unity使用的类中。有了这个Unity知道它应该/可以序列化类。

Unity序列化的关键字是 Serializable 和 SerializeField,具体描述可以翻阅api。

假设我们在写一个组件需要把一个引用字段里的属性都显示出来供配置,那么,根据上面的介绍我们要分两步。

前文链接:自定义menuItem
下文:针对自定义特性创建PropertyDrawer

注:配套案例可在 EditorExtensionDemo 仓库中查看。

Unity3D编辑器扩展——扩展自己的组件

前面已经写了三篇:

Unity3D编辑器扩展(一)——定义自己的菜单按钮

Unity3D编辑器扩展(二)——定义自己的窗口

Unity3D编辑器扩展(三)——使用GUI绘制窗口

今天写第四篇,扩展自己的自定义组件。

通常我们使用继承自 Editor 的自定义编辑器类,来扩展自己的组件的检视面板和编辑器,并配合 CustomEditor 特性语法,附加该编辑器到一个自定义组件。

首先我们先定义一个组件 Player

1 using UnityEngine;
2 
3 public class Player : MonoBehaviour
4 {
5     public int armor = 80;      //护甲
6     public int attack = 100;    //攻击力
7 }

一个简单的 Player 组件,有护甲和攻击力两个属性,挂载后,效果如下:

技术分享图片

接下来我们对 Player 进行扩展,代码如下:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Player))]
public class EditorTest : Editor 
{
    public override void OnInspectorGUI()
    {
        var _target = (Player)(serializedObject.targetObject);
        _target.armor = EditorGUILayout.IntSlider("护甲", _target.armor, 0, 100);
        ProgressBar(_target.armor / 100f, "护甲");
        _target.attack = EditorGUILayout.IntSlider("攻击力", _target.attack, 0, 100);
        ProgressBar(_target.attack / 100f, "攻击力");
    }
    private void ProgressBar(float value, string label)
    {
        Rect rect = GUILayoutUtility.GetRect(18, 18);
        EditorGUI.ProgressBar(rect, value, label);
        EditorGUILayout.Space();
    }
}

效果图:

技术分享图片

是不是感觉漂亮了很多,直观了很多。这样我们就可以把很多UI控件扩展到我们的组件上,显得高大上。

实效上面这种效果,还有另外一种方法:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Player))]
public class EditorTest : Editor 
{
    private SerializedProperty attack;
    private SerializedProperty armor;
    void OnEnable()
    {
        attack = serializedObject.FindProperty("attack");
        armor = serializedObject.FindProperty("armor");
    }
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        EditorGUILayout.IntSlider(armor, 0, 100, new GUIContent("护甲"));
        ProgressBar(armor.intValue / 100f, "护甲");
        EditorGUILayout.IntSlider(attack, 0, 100, new GUIContent("攻击力"));
        ProgressBar(attack.intValue / 100f, "攻击力");
        serializedObject.ApplyModifiedProperties();
    }
    private void ProgressBar(float value, string label)
    {
        Rect rect = GUILayoutUtility.GetRect(18, 18);
        EditorGUI.ProgressBar(rect, value, label);
        EditorGUILayout.Space();
    }
}

这种方法和第一种方法效果是一样的,就不上图了。

 扩展自定义组件我们除了写编辑器类以外,还会用到很多特性,特性的使用在下一节。

 

以上是关于编辑器扩展基础3-自定义PropertyDrawer的主要内容,如果未能解决你的问题,请参考以下文章

Unity 编辑器扩展七 Property Attributes

UnityEditor编辑器扩展开发-自定义Shader入门

UnityEditor编辑器扩展开发-自定义Shader入门

富文本编辑器 quill.js 开发: 自定义格式扩展

Unity 之 自定义编辑器布局

黄聪:wordpress如何扩展TinyMCE编辑器,添加自定义按钮及功能