Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. We are looking for your feedback about Templates! Tell us about your experiences by taking our survey.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    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:
    497
    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:
    1,072
    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
unityunity