Custom editor controls in Unity - Part 4: Property drawers

Often it is nice to customize the way that some properties are presented in the inspector but you don’t necessarily want to define an entire custom inspector. Fortunately Unity has a feature that enables you to customize the drawing of properties without having to define how the entire inspector of a component should work.

Custom property drawers can be assigned to a specific type of value (i.e. a custom struct, class, enum) or to an attribute that can then be used to annotate properties where the custom drawer is useful.

In this post I am going to demonstrate how to use the MyGUI.FlagToggleGrid control that was developed in the previous part to edit properties in a custom MonoBehaviour.

Screenshot of the property drawer in action

The first step is to implement the attribute itself:

using UnityEngine;

public sealed class FlagToggleGridAttribute : PropertyAttribute
{
    private int flagCount = 4;
    

    public int FlagCount {
        get { return this.flagCount; }
        set { this.flagCount = value; }
    }
}

The attribute can then be used to annotate the relevant properties of your behaviors:

using UnityEngine;

public sealed class NewMonoBehaviour : MonoBehaviour
{
    public bool someOtherField = false;

    [Space]
    [FlagToggleGrid]
    public int defaultFlagCount = 0;

    [Space]
    [FlagToggleGrid(FlagCount = 16)]
    public int row1 = 0;
    [FlagToggleGrid(FlagCount = 16)]
    public int row2 = 0;
}

The custom property drawer can then be associated with our FlagToggleGridAttribute:

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(FlagToggleGridAttribute))]
public sealed class FlagToggleGridPropertyDrawer : PropertyDrawer
{
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return 42f;
    }

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        var attr = (FlagToggleGridAttribute)this.attribute;
        MyGUI.FlagToggleGrid(position, property, label, attr.FlagCount);
    }
}

And since the MyGUI.FlagToggleGrid control has support for EditorGUI.showMixedValue we see the mixed value state when multiple game objects are selected with differing values:

Screenshot of the property drawer with mixed values

See: Part 5: Custom styles