I’ve written a “wrapper” function, mainly for a general PropertyDrawer, which actual uses the enum values. However, this changes the Nothing and Everything behaviour, but all enum values work fine, even combined values.
// Have to be defined somewhere in a runtime script file
// BitMaskAttribute.cs
public class BitMaskAttribute : PropertyAttribute
{
public System.Type propType;
public BitMaskAttribute(System.Type aType)
{
propType = aType;
}
}
This should go into an editor script:
// /editor/EnumBitMaskPropertyDrawer.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
public static class EditorExtension
{
public static int DrawBitMaskField (Rect aPosition, int aMask, System.Type aType, GUIContent aLabel)
{
var itemNames = System.Enum.GetNames(aType);
var itemValues = System.Enum.GetValues(aType) as int[];
int val = aMask;
int maskVal = 0;
for(int i = 0; i < itemValues.Length; i++)
{
if (itemValues[i] != 0)
{
if ((val & itemValues[i]) == itemValues[i])
maskVal |= 1 << i;
}
else if (val == 0)
maskVal |= 1 << i;
}
int newMaskVal = EditorGUI.MaskField(aPosition, aLabel, maskVal, itemNames);
int changes = maskVal ^ newMaskVal;
for(int i = 0; i < itemValues.Length; i++)
{
if ((changes & (1 << i)) != 0) // has this list item changed?
{
if ((newMaskVal & (1 << i)) != 0) // has it been set?
{
if (itemValues[i] == 0) // special case: if "0" is set, just set the val to 0
{
val = 0;
break;
}
else
val |= itemValues[i];
}
else // it has been reset
{
val &= ~itemValues[i];
}
}
}
return val;
}
}
[CustomPropertyDrawer(typeof(BitMaskAttribute))]
public class EnumBitMaskPropertyDrawer : PropertyDrawer
{
public override void OnGUI (Rect position, SerializedProperty prop, GUIContent label)
{
var typeAttr = attribute as BitMaskAttribute;
// Add the actual int value behind the field name
label.text = label.text + "("+prop.intValue+")";
prop.intValue = EditorExtension.DrawBitMaskField(position, prop.intValue, typeAttr.propType, label);
}
}
Now just imagine this example:
public enum EMyEnum
{
None = 0x00,
Cow = 0x01,
Chicken = 0x02,
Cat = 0x04,
Dog = 0x08,
CowChicken = 0x03,
CatDog = 0x0C,
All = 0x0F,
}
public class Example : MonoBehaviour
{
[BitMask(typeof(EMyEnum))]
public EMyEnum someMask;
}
This will automatically draw my modified enum-mask field.
ps: I just fixed the completely broken code formatting due to the Unity Answers migration. I haven’t had the time to test if the code actually works. There were a lot of messed up things (especially [i] being replaced with italics tags).