• Unity编辑器扩展——PropertyDrawer


    一:前言

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


    二:注意事项

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


    三:代码实现

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

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


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

    1. using UnityEngine;
    2. using UnityEditor;
    3. using System;
    4. public sealed class TestRangeAttribute : PropertyAttribute
    5. {
    6. public readonly float min;
    7. public readonly float max;
    8. public TestRangeAttribute(float min, float max)
    9. {
    10. this.min = min;
    11. this.max = max;
    12. }
    13. }
    14. [CustomPropertyDrawer(typeof(TestRangeAttribute))]
    15. public class TestRangeDrawer : PropertyDrawer
    16. {
    17. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    18. {
    19. TestRangeAttribute range = attribute as TestRangeAttribute;
    20. if (property.propertyType == SerializedPropertyType.Float)
    21. {
    22. EditorGUI.Slider(position, property, range.min, range.max, label);
    23. }
    24. else if (property.propertyType == SerializedPropertyType.Integer)
    25. {
    26. EditorGUI.IntSlider(position, property, Convert.ToInt32(range.min), Convert.ToInt32(range.max), label);
    27. }
    28. else
    29. {
    30. EditorGUI.LabelField(position, label.text, "error");
    31. }
    32. }
    33. }

    五:案例——自定义特性

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

    1. using UnityEngine;
    2. using UnityEditor;
    3. public sealed class TimeAttribute : HeaderAttribute
    4. {
    5. public bool showDay;
    6. public bool showHour;
    7. public bool showMin;
    8. public bool showSec;
    9. public TimeAttribute(bool showDay = false, bool showHour = false, bool showMin = false, bool showSec = false)
    10. {
    11. this.showDay = showDay;
    12. this.showHour = showHour;
    13. this.showMin = showMin;
    14. this.showSec = showSec;
    15. }
    16. }
    17. [CustomPropertyDrawer(typeof(TimeAttribute))]
    18. public class TimeAttributeDrawer : PropertyDrawer
    19. {
    20. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    21. {
    22. EditorGUI.PropertyField(new Rect(position.x, position.y, position.width * 0.6f, position.height), property);
    23. EditorGUI.LabelField(new Rect(position.x + position.width * 0.6f, position.y, position.width * 0.4f, position.height), GetTimeString(property.floatValue));
    24. }
    25. string GetTimeString(float sec)
    26. {
    27. TimeAttribute target = attribute as TimeAttribute;
    28. if (target.showDay)
    29. {
    30. int day = (int)(sec / (60 * 60 * 60));
    31. return $"{day}天";
    32. }
    33. else if (target.showHour)
    34. {
    35. int hour = (int)(sec / (60 * 60));
    36. return $"{hour}小时";
    37. }
    38. else if (target.showMin)
    39. {
    40. int min = (int)(sec / 60);
    41. return $"{min}分钟";
    42. }
    43. else if (target.showSec)
    44. {
    45. return $"{sec}秒";
    46. }
    47. else
    48. {
    49. return "";
    50. }
    51. }
    52. }

  • 相关阅读:
    【OpenCV】多版本那是interesting
    2000-2020上市公司全要素生产率LP方法含原始数据和Stata代码
    软考高级系统架构设计师系列论文真题三:论软件设计模式及其应用
    RocketMQ快速实战以及集群架构原理详解
    嵌入式学习路线图
    【JavaScript】Web API基础(五)
    错题汇总14
    基于SpringBoot的智能推荐的卫生健康系统
    JavaGUI------------常用的窗体(JFrame、Dialog)
    如何优雅的实现接口统一调用
  • 原文地址:https://blog.csdn.net/LLLLL__/article/details/126648763