Skip to content

Instantly share code, notes, and snippets.

@MPozek
Created August 30, 2021 07:37
Show Gist options
  • Save MPozek/f13eea941a7d59b7d4bdf0f83a2e4534 to your computer and use it in GitHub Desktop.
Save MPozek/f13eea941a7d59b7d4bdf0f83a2e4534 to your computer and use it in GitHub Desktop.
A better enum dropdown drawer for Unity
using System;
using UnityEditor;
using UnityEngine;
using UnityEditor.IMGUI.Controls;
[CustomPropertyDrawer(typeof(Enum), true)]
public class EnumPropertyDrawer : PropertyDrawer
{
private AdvancedStringOptionsDropdown _dropdown;
private SerializedProperty _property;
private Rect _buttonRect;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (_dropdown == null)
{
_dropdown = new AdvancedStringOptionsDropdown(property.enumDisplayNames);
_dropdown.OnOptionSelected += OnDropdownOptionSelected;
}
_property = property;
position = EditorGUI.PrefixLabel(position, label);
if (Event.current.type == EventType.Repaint)
_buttonRect = position;
if (GUI.Button(
position,
new GUIContent(property.enumDisplayNames[property.enumValueIndex]),
EditorStyles.popup
))
{
_dropdown.Show(_buttonRect);
}
}
private void OnDropdownOptionSelected(int index)
{
_property.enumValueIndex = index;
_property.serializedObject.ApplyModifiedProperties();
}
}
public class AdvancedStringOptionsDropdown : AdvancedDropdown
{
private string[] _enumNames;
public event Action<int> OnOptionSelected;
public AdvancedStringOptionsDropdown(string[] stringOptions) : base(new AdvancedDropdownState())
{
_enumNames = stringOptions;
}
protected override void ItemSelected(AdvancedDropdownItem item)
{
OnOptionSelected?.Invoke(item.id);
}
protected override AdvancedDropdownItem BuildRoot()
{
var root = new AdvancedDropdownItem("");
for (int i = 0; i < _enumNames.Length; i++)
{
var item = new AdvancedDropdownItem(_enumNames[i]);
item.id = i;
root.AddChild(item);
}
return root;
}
}
@apautrot
Copy link

apautrot commented Jan 19, 2022

The code doesn't work for arrays of arrays of enums, because the same drawer instance is reused for each elements.
( => each calls made to OnGUI is rewriting the property that is to be updated in OnDropdownOptionSelected )

To fix this, simply move the line 26 "_property = property;" to line 39 : this make sure that the updated property is the one that correspond to the one on which the drop down is opened.

@somedeveloper00
Copy link

Great & easy fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment