赞
踩
PropertyDrawer允许我们控制一个属性的Inspector检视面板的GUI如何绘制。
首先看几个Unity中内置的PropertyDrawers:
- [Range(0, 20)]
- public int intValue = 10;
-
- [Header("名称")]
- public string nameStr;
-
- [SerializeField]
- private float floatValue = 10f;
如图所示,Range可以限制intValue的取值范围0~20,Header可以给字段做一些描述或备注,SerializeField允许我们讲一个Private私有字段同Public字段一样显示在Inspector检视面板上。
那么如何自定义一个PropertyDrawer?以一个Time特性为例:
- [Time]
- public float time = 473.35f;
我们希望将一个float类型的描述时间的字段在Inspector面板上以00:00时间格式进行显示:
首先先定义Time特性:
- using UnityEngine;
-
- namespace SK.Framework
- {
- /// <summary>
- /// 时间特性
- /// </summary>
- public sealed class TimeAttribute : PropertyAttribute
- {
- /// <summary>
- /// 显示小时
- /// </summary>
- public readonly bool displayHours;
- /// <summary>
- /// 显示毫秒
- /// </summary>
- public readonly bool displayMillseconds;
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="displayHours">显示小时</param>
- /// <param name="displayMillseconds">显示毫秒</param>
- public TimeAttribute (bool displayHours = false, bool displayMillseconds = false)
- {
- this.displayHours = displayHours;
- this.displayMillseconds = displayMillseconds;
- }
- }
- }
有了TimeAttribute后,我们来自定义它如何在Inspector上进行绘制:
需要在Editor文件夹中创建TimeDrawer类,引入UnityEditor命名空间并继承PropertyDrawer
然后Override重写OnGUI方法来实现绘制,GetPropertyHeight用来定义绘制属性的高度
- using System;
- using UnityEngine;
- using UnityEditor;
-
- namespace SK.Framework
- {
- /// <summary>
- /// 时间特性绘制
- /// </summary>
- [CustomPropertyDrawer(typeof(TimeAttribute))]
- public sealed class TimeDrawer : PropertyDrawer
- {
- public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
- {
- if(property.propertyType == SerializedPropertyType.Float)
- {
- property.floatValue = EditorGUI.FloatField(new Rect(position.x, position.y, position.width * 0.6f, position.height), label, property.floatValue);
- EditorGUI.LabelField(new Rect(position.x + position.width * 0.6f, position.y, position.width * 0.4f, position.height), GetTimeFormat(property.floatValue));
- }
- else
- {
- EditorGUI.HelpBox(new Rect(position.x, position.y, position.width, position.height), "只支持float类型属性", MessageType.Error);
- }
- }
-
- public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
- {
- return base.GetPropertyHeight(property, label);
- }
-
- private string GetTimeFormat(float secondsTime)
- {
- TimeAttribute ta = attribute as TimeAttribute;
- //显示小时不显示毫秒
- if (ta.displayHours && !ta.displayMillseconds)
- {
- int l = Convert.ToInt32(secondsTime);
- int hours = l / 3600;
- int minutes = l % 3600 / 60;
- int seconds = l % 3600 % 60;
- return string.Format("({0:D2}:{1:D2}:{2:D2} [hh:mm:ss])", hours, minutes, seconds);
- }
- //显示毫秒不显示小时
- else if(!ta.displayHours && ta.displayMillseconds)
- {
- int l = Convert.ToInt32(secondsTime * 1000);
- int minutes = l / 60000;
- int seconds = l % 60000 / 1000;
- int millSeconds = l % 60000 % 1000;
- return string.Format("({0:D2}:{1:D2}.{2:D3} [mm:ss.fff)]", minutes, seconds, millSeconds);
- }
- //既显示小时也显示毫秒
- else if (ta.displayHours && ta.displayMillseconds)
- {
- int l = Convert.ToInt32(secondsTime * 1000);
- int hours = l / 3600000;
- int minutes = l % 3600000 / 60000;
- int seconds = l % 3600000 % 60000 / 1000;
- int millSeconds = l % 3600000 % 60000 % 1000;
- return string.Format("({0:D2}:{1:D2}:{2:D2}.{3:D3} [hh:mm:ss.fff)]", hours, minutes, seconds, millSeconds);
- }
- //既不显示小时也不显示毫秒
- else
- {
- int l = Convert.ToInt32(secondsTime);
- int minutes = l / 60;
- int seconds = l % 60;
- return string.Format("({0:D2}:{1:D2}) [mm:ss]", minutes, seconds);
- }
- }
- }
- }
TimeAttribute可以控制是否显示小时、是否显示毫秒:
- [Time(true, true)]
- public float time1 = 473.35f;
- [Time(true, false)]
- public float time2 = 473.35f;
- [Time(false, true)]
- public float time3 = 473.35f;
- [Time]
- public float time4 = 473.35f;
- [Time]
- public int time5 = 0;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。