Manage lots of enum choices in inspector
I'm writing a RPG, and to keep track of individual item types (ex: each weapon, each resource &c), I use an enum.
At the moment I have 90 or so entries, and so when I need to find a specific item type in the inspector, it's a bit of a headache. The inspector supports searching by the first character (and only that), but that's not that helpful
Is there a way of managing enum values in the inspector - such as being able to group them, or get a better search instead of going through the dropdown?
Answer by Hellium · Oct 31, 2021 at 01:24 PM
Using an enum might not be the best solution in your case. But I don't know your system enough to judge.
Anyway, InspectorName attribute lets you group enum values.
public enum Item
{
[InspectorName("Weapon/Melee/Sword")]
Sword,
[InspectorName("Weapon/Melee/Axe")]
Axe,
[InspectorName("Weapon/Ranged/Bow")]
Bow,
[InspectorName("Weapon/Magic/Wand")]
Wand,
[InspectorName("Weapon/Magic/Staff")]
Staff,
[InspectorName("Equipment/Helmet")]
Helmet,
[InspectorName("Equipment/Armor")]
Armor,
[InspectorName("Consumable/HealthPotion")]
HealthPotion,
[InspectorName("Consumable/ManaPotion")]
ManaPotion,
[InspectorName("Consumable/Food")]
Food,
Coin
}
If you want the enum to be searchable, you'll need more code:
// SearchableAttribute.cs in your Assets folder
using UnityEngine;
public class SearchableAttribute : PropertyAttribute { }
// SearchableAttributeDrawer.cs >>> IN AN 'Editor' FOLDER <<<
using System;
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(SearchableAttribute))]
public class SearchableAttributeDrawer : PropertyDrawer
{
private string search;
private string[] options;
private GUIStyle searchTextFieldStyle;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float height = base.GetPropertyHeight(property, label);
if (property.propertyType == SerializedPropertyType.Enum)
height = height * 2 + EditorGUIUtility.standardVerticalSpacing;
return height;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (property.propertyType == SerializedPropertyType.Enum)
{
if (searchTextFieldStyle == null)
searchTextFieldStyle = GUI.skin.FindStyle("ToolbarSeachTextField");
if (options == null)
UpdateOptions(property.enumDisplayNames);
Rect searchRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
DrawSearchBar(searchRect, label, property.enumDisplayNames);
Rect popupRect = new Rect(position.x, searchRect.y + searchRect.height + EditorGUIUtility.standardVerticalSpacing, position.width, EditorGUIUtility.singleLineHeight);
DrawEnumPopup(popupRect, property);
}
else
{
EditorGUI.PropertyField(position, property, label);
}
}
private void DrawSearchBar(Rect position, GUIContent label, string[] allOptions)
{
EditorGUI.BeginChangeCheck();
search = EditorGUI.TextField(position, label, search, searchTextFieldStyle);
if(EditorGUI.EndChangeCheck())
UpdateOptions(allOptions);
}
private void DrawEnumPopup(Rect position, SerializedProperty property)
{
Rect fieldRect = EditorGUI.PrefixLabel(position, new GUIContent(" "));
int currentIndex = Array.IndexOf(options, property.enumDisplayNames[property.enumValueIndex]);
int selectedIndex = EditorGUI.Popup(fieldRect, currentIndex, options);
if (selectedIndex >= 0)
{
int newIndex = Array.IndexOf(property.enumDisplayNames, options[selectedIndex]);
if (newIndex != currentIndex)
{
property.enumValueIndex = newIndex;
search = string.Empty;
UpdateOptions(property.enumDisplayNames);
}
}
}
private void UpdateOptions(string[] allOptions)
{
options = Array.FindAll(allOptions, name => string.IsNullOrEmpty(search) || name.IndexOf(search, StringComparison.InvariantCultureIgnoreCase) >= 0);
}
}
// In your code
[Searchable]
public Item Item;
The inspector name is incredibly helpful. Thank you so much.
Not sure about the enums myself either, but if I need to make references in crafting (ex: sword needs 5 ingots, and 3 coal), I thought enums would be the safest way to keep references.
Your answer
![](https://koobas.hobune.stream/wayback/20220613044829im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Why does rotating via viewport give different values than inspector rotations? 2 Answers
Collider is deleting itself when I press play 0 Answers
Is there a way for a public/serializedfield to be uneditable and just grayed out in the inspector? 1 Answer
assign variable by inspector failed... 2 Answers