当前位置:   article > 正文

七、Unity编辑器开发之PropertyDrawer

propertydrawer

PropertyDrawer允许我们控制一个属性的Inspector检视面板的GUI如何绘制。

首先看几个Unity中内置的PropertyDrawers:

  1. [Range(0, 20)]
  2. public int intValue = 10;
  3. [Header("名称")]
  4. public string nameStr;
  5. [SerializeField]
  6. private float floatValue = 10f;

如图所示,Range可以限制intValue的取值范围0~20,Header可以给字段做一些描述或备注,SerializeField允许我们讲一个Private私有字段同Public字段一样显示在Inspector检视面板上。

那么如何自定义一个PropertyDrawer?以一个Time特性为例:

  1. [Time]
  2. public float time = 473.35f;

我们希望将一个float类型的描述时间的字段在Inspector面板上以00:00时间格式进行显示:

首先先定义Time特性:

  1. using UnityEngine;
  2. namespace SK.Framework
  3. {
  4. /// <summary>
  5. /// 时间特性
  6. /// </summary>
  7. public sealed class TimeAttribute : PropertyAttribute
  8. {
  9. /// <summary>
  10. /// 显示小时
  11. /// </summary>
  12. public readonly bool displayHours;
  13. /// <summary>
  14. /// 显示毫秒
  15. /// </summary>
  16. public readonly bool displayMillseconds;
  17. /// <summary>
  18. /// 构造函数
  19. /// </summary>
  20. /// <param name="displayHours">显示小时</param>
  21. /// <param name="displayMillseconds">显示毫秒</param>
  22. public TimeAttribute (bool displayHours = false, bool displayMillseconds = false)
  23. {
  24. this.displayHours = displayHours;
  25. this.displayMillseconds = displayMillseconds;
  26. }
  27. }
  28. }

有了TimeAttribute后,我们来自定义它如何在Inspector上进行绘制:

需要在Editor文件夹中创建TimeDrawer类,引入UnityEditor命名空间并继承PropertyDrawer

然后Override重写OnGUI方法来实现绘制,GetPropertyHeight用来定义绘制属性的高度

  1. using System;
  2. using UnityEngine;
  3. using UnityEditor;
  4. namespace SK.Framework
  5. {
  6. /// <summary>
  7. /// 时间特性绘制
  8. /// </summary>
  9. [CustomPropertyDrawer(typeof(TimeAttribute))]
  10. public sealed class TimeDrawer : PropertyDrawer
  11. {
  12. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  13. {
  14. if(property.propertyType == SerializedPropertyType.Float)
  15. {
  16. property.floatValue = EditorGUI.FloatField(new Rect(position.x, position.y, position.width * 0.6f, position.height), label, property.floatValue);
  17. EditorGUI.LabelField(new Rect(position.x + position.width * 0.6f, position.y, position.width * 0.4f, position.height), GetTimeFormat(property.floatValue));
  18. }
  19. else
  20. {
  21. EditorGUI.HelpBox(new Rect(position.x, position.y, position.width, position.height), "只支持float类型属性", MessageType.Error);
  22. }
  23. }
  24. public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  25. {
  26. return base.GetPropertyHeight(property, label);
  27. }
  28. private string GetTimeFormat(float secondsTime)
  29. {
  30. TimeAttribute ta = attribute as TimeAttribute;
  31. //显示小时不显示毫秒
  32. if (ta.displayHours && !ta.displayMillseconds)
  33. {
  34. int l = Convert.ToInt32(secondsTime);
  35. int hours = l / 3600;
  36. int minutes = l % 3600 / 60;
  37. int seconds = l % 3600 % 60;
  38. return string.Format("({0:D2}:{1:D2}:{2:D2} [hh:mm:ss])", hours, minutes, seconds);
  39. }
  40. //显示毫秒不显示小时
  41. else if(!ta.displayHours && ta.displayMillseconds)
  42. {
  43. int l = Convert.ToInt32(secondsTime * 1000);
  44. int minutes = l / 60000;
  45. int seconds = l % 60000 / 1000;
  46. int millSeconds = l % 60000 % 1000;
  47. return string.Format("({0:D2}:{1:D2}.{2:D3} [mm:ss.fff)]", minutes, seconds, millSeconds);
  48. }
  49. //既显示小时也显示毫秒
  50. else if (ta.displayHours && ta.displayMillseconds)
  51. {
  52. int l = Convert.ToInt32(secondsTime * 1000);
  53. int hours = l / 3600000;
  54. int minutes = l % 3600000 / 60000;
  55. int seconds = l % 3600000 % 60000 / 1000;
  56. int millSeconds = l % 3600000 % 60000 % 1000;
  57. return string.Format("({0:D2}:{1:D2}:{2:D2}.{3:D3} [hh:mm:ss.fff)]", hours, minutes, seconds, millSeconds);
  58. }
  59. //既不显示小时也不显示毫秒
  60. else
  61. {
  62. int l = Convert.ToInt32(secondsTime);
  63. int minutes = l / 60;
  64. int seconds = l % 60;
  65. return string.Format("({0:D2}:{1:D2}) [mm:ss]", minutes, seconds);
  66. }
  67. }
  68. }
  69. }

TimeAttribute可以控制是否显示小时、是否显示毫秒:

  1. [Time(true, true)]
  2. public float time1 = 473.35f;
  3. [Time(true, false)]
  4. public float time2 = 473.35f;
  5. [Time(false, true)]
  6. public float time3 = 473.35f;
  7. [Time]
  8. public float time4 = 473.35f;
  9. [Time]
  10. public int time5 = 0;

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号