Custom attribute drawers always replace class drawers?

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.

using System;
using UnityEngine;

namespace PixelComrades {
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
    public class ItemTypeAttribute : PropertyAttribute {
        public ItemTypes SpecifiedType;

        public ItemTypeAttribute(ItemTypes itemType) {
            SpecifiedType = itemType;
        }

        public bool ShouldShow(ItemTemplate template) {
            if (template == null || (SpecifiedType & template.Type) != 0) {
                return true;
            }
            return false;
        }
    }
}
using UnityEngine;
using UnityEditor;

namespace PixelComrades {
    [CustomPropertyDrawer(typeof(ItemTypeAttribute))]
    public class ItemTypeDrawer : PropertyDrawer {

        private ItemTypeAttribute ItemAttribute {
            get {
                return (ItemTypeAttribute)attribute;
            }
        }

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
            var item = property.serializedObject.targetObject as ItemTemplate;
            if (!ItemAttribute.ShouldShow(item)) {
                return;
            }
            ParentedValue propertyInstance = fieldInfo.GetValue(property.serializedObject.targetObject) as ParentedValue;
            if (propertyInstance != null) {
                ParentedDrawer.DisplayParentedDrawer(position,property,label,fieldInfo);
            }
            else {
                EditorGUI.PropertyField(position, property, label, true);
            }
        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
            var item = property.serializedObject.targetObject as ItemTemplate;
            if (!ItemAttribute.ShouldShow(item)) {
                return -2f;
            }
            return base.GetPropertyHeight(property, label);
        }
    }
}
1 Like

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.