Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Custom attribute drawers always replace class drawers?

Discussion in 'Immediate Mode GUI (IMGUI)' started by Silly_Rollo, Mar 15, 2017.

  1. Silly_Rollo

    Silly_Rollo

    Joined:
    Dec 21, 2012
    Posts:
    482
    It seems like if you have an attribute drawer you can't show a custom class drawer. I reflected the unityeditor.dll and it seems like they pop an error just to remind you to insert logic so you can't just call base.OnGUI. Is there some reason for that? Is there some way around it?

    My crappy hack is to make my custom class drawers have a public static method to also display themselves so the Attribute can call it directly. Obviously this is kinda dumb as I'd need to add that for every custom class drawer.

    Code (csharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4.  
    5. namespace PixelComrades {
    6.     [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
    7.     public class ItemTypeAttribute : PropertyAttribute {
    8.         public ItemTypes SpecifiedType;
    9.  
    10.         public ItemTypeAttribute(ItemTypes itemType) {
    11.             SpecifiedType = itemType;
    12.         }
    13.  
    14.         public bool ShouldShow(ItemTemplate template) {
    15.             if (template == null || (SpecifiedType & template.Type) != 0) {
    16.                 return true;
    17.             }
    18.             return false;
    19.         }
    20.     }
    21. }
    22.  
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4.  
    5. namespace PixelComrades {
    6.     [CustomPropertyDrawer(typeof(ItemTypeAttribute))]
    7.     public class ItemTypeDrawer : PropertyDrawer {
    8.  
    9.         private ItemTypeAttribute ItemAttribute {
    10.             get {
    11.                 return (ItemTypeAttribute)attribute;
    12.             }
    13.         }
    14.  
    15.         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
    16.             var item = property.serializedObject.targetObject as ItemTemplate;
    17.             if (!ItemAttribute.ShouldShow(item)) {
    18.                 return;
    19.             }
    20.             ParentedValue propertyInstance = fieldInfo.GetValue(property.serializedObject.targetObject) as ParentedValue;
    21.             if (propertyInstance != null) {
    22.                 ParentedDrawer.DisplayParentedDrawer(position,property,label,fieldInfo);
    23.             }
    24.             else {
    25.                 EditorGUI.PropertyField(position, property, label, true);
    26.             }
    27.         }
    28.  
    29.         public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
    30.             var item = property.serializedObject.targetObject as ItemTemplate;
    31.             if (!ItemAttribute.ShouldShow(item)) {
    32.                 return -2f;
    33.             }
    34.             return base.GetPropertyHeight(property, label);
    35.         }
    36.     }
    37. }
    38.  
     
    Last edited: Mar 15, 2017
    infinitypbr likes this.
  2. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    781
    Yeah, I've struggled with this too, especially with multiple Attribute Drawers.

    Hoping that one day Unity will support multiple.

    Actually... I doubt this will happen, because PropertyDrawrs can override the height. Would get real messy if different drawers were setting different heights.
     
    Last edited: Mar 16, 2017