Unity Editor: Enum Flags as Toggle Buttons

Note: We’ve since cleaned up this code, added view options and released it as a cheap plugin on the Unity Asset Store.

Working on the content tools for our current project I needed enum flags, unfortunately the Unity Editor doesn’t natively support those. Looking around I found a few implementations of enum flags as dropdowns similar to the layer mask dropdown in Unity itself. While that’s pretty neat it has the disadvantage that you don’t have a quick overview over which flags are on and which are off. To that end I’ve built a new custom PropertyDrawer that displays EnumFlags as a neat row of toggle buttons:

Toggle Buttons in Action

Toggle Buttons in Action

All you need is two scripts and an attribute. Also note that your enum needs to start with 1, not 0 and that each value needs to be a power of two (1, 2, 4, 8 etc.)

And here’s the code:

EnumFlagAttribute.cs

This file needs to go in a regular scripts folder (not Editor!). It creates the [EnumFlags] attribute.

using UnityEngine;

public class EnumFlagAttribute : PropertyAttribute
{
	public EnumFlagAttribute() {}
}

EnumFlagDrawer.cs

This one goes into an Editor folder. It manages the display of fields that have the [EnumFlags] attribute.

using System;
using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(EnumFlagAttribute))]
public class EnumFlagsAttributeDrawer : PropertyDrawer
{

	public override void OnGUI(Rect _position, SerializedProperty _property, GUIContent _label)
	{
		int buttonsIntValue = 0;
		int enumLength = _property.enumNames.Length;
		bool[] buttonPressed = new bool[enumLength];
		float buttonWidth = (_position.width - EditorGUIUtility.labelWidth) / enumLength;

		EditorGUI.LabelField(new Rect(_position.x, _position.y, EditorGUIUtility.labelWidth, _position.height), _label);

		EditorGUI.BeginChangeCheck ();

		for (int i = 0; i < enumLength; i++) {

			// Check if the button is/was pressed 
			if ( ( _property.intValue & (1 << i) ) == 1 << i ) {
				buttonPressed[i] = true;
			}

			Rect buttonPos = new Rect (_position.x + EditorGUIUtility.labelWidth + buttonWidth * i, _position.y, buttonWidth, _position.height);

			buttonPressed[i] = GUI.Toggle(buttonPos, buttonPressed[i], _property.enumNames[i],  "Button");

			if (buttonPressed[i])
				buttonsIntValue += 1 << i;
		}

		if (EditorGUI.EndChangeCheck()) {
			_property.intValue = buttonsIntValue;
		}
	}
}

I hope you enjoy it. And if you’ve got comments or ideas, let me know!

– Martin

Update: Note about the Unity Asset Store release of an updated version of this code added.