Unity编辑器扩展——PropertyDrawer

Posted Hello Bug.

tags:

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

一:前言

PropertyDrawer允许我们自定义一个属性在Inspector面板的如何绘制


二:注意事项

——PropertyDrawer只对可序列化的字段有效
——OnGUI方法里只能使用GUI相关方法(使用EditorGUI绘制),不能使用Layout相关方法


三:代码实现

需要两个类
——定义一个类,继承自PropertyAttribute,为了添加Header时才调用此特性(如果不需要Header则不用定义)
——定义一个类,继承自PropertyDrawer,为了绘制此属性

OnGUI:重写此方法可以自定义此字段在面板上如果绘制。position坐标是从左上角开始
GetPropertyHeight:重写此方法可以指定此字段的GUI像素高度(默认是18)


四:案例——模拟内置的Range特性

using UnityEngine;
using UnityEditor;
using System;

public sealed class TestRangeAttribute : PropertyAttribute

    public readonly float min;
    public readonly float max;

    public TestRangeAttribute(float min, float max)
    
        this.min = min;
        this.max = max;
    


[CustomPropertyDrawer(typeof(TestRangeAttribute))]
public class TestRangeDrawer : PropertyDrawer

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    
        TestRangeAttribute range = attribute as TestRangeAttribute;

        if (property.propertyType == SerializedPropertyType.Float)
        
            EditorGUI.Slider(position, property, range.min, range.max, label);
        
        else if (property.propertyType == SerializedPropertyType.Integer)
        
            EditorGUI.IntSlider(position, property, Convert.ToInt32(range.min), Convert.ToInt32(range.max), label);
        
        else
        
            EditorGUI.LabelField(position, label.text, "error");
        
    

五:案例——自定义特性

创建一个自定义的Time特性,可以显示转换成的天、时、分、秒

using UnityEngine;
using UnityEditor;

public sealed class TimeAttribute : HeaderAttribute

    public bool showDay;
    public bool showHour;
    public bool showMin;
    public bool showSec;

    public TimeAttribute(bool showDay = false, bool showHour = false, bool showMin = false, bool showSec = false)
    
        this.showDay = showDay;
        this.showHour = showHour;
        this.showMin = showMin;
        this.showSec = showSec;
    


[CustomPropertyDrawer(typeof(TimeAttribute))]
public class TimeAttributeDrawer : PropertyDrawer

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    
        EditorGUI.PropertyField(new Rect(position.x, position.y, position.width * 0.6f, position.height), property);
        EditorGUI.LabelField(new Rect(position.x + position.width * 0.6f, position.y, position.width * 0.4f, position.height), GetTimeString(property.floatValue));
    

    string GetTimeString(float sec)
    
        TimeAttribute target = attribute as TimeAttribute;
        if (target.showDay)
        
            int day = (int)(sec / (60 * 60 * 60));
            return $"day天";
        
        else if (target.showHour)
        
            int hour = (int)(sec / (60 * 60));
            return $"hour小时";
        
        else if (target.showMin)
        
            int min = (int)(sec / 60);
            return $"min分钟";
        
        else if (target.showSec)
        
            return $"sec秒";
        
        else
        
            return "";
        
    

以上是关于Unity编辑器扩展——PropertyDrawer的主要内容,如果未能解决你的问题,请参考以下文章

unity shader 编辑器扩展类 ShaderGUI

Unity 扩展编辑器

Unity编辑器扩展chapter1

Unity扩展编辑器五

Unity编辑器扩展

Unity编辑器扩展: 程序化打图集工具