Skip to content

Instantly share code, notes, and snippets.

@ANamelessGhoul
Last active February 10, 2023 11:28
Show Gist options
  • Select an option

  • Save ANamelessGhoul/c0ef4fc3ea4b3cae532d06e38e1aaf9b to your computer and use it in GitHub Desktop.

Select an option

Save ANamelessGhoul/c0ef4fc3ea4b3cae532d06e38e1aaf9b to your computer and use it in GitHub Desktop.
A Dictionary that automatically resizes to the size of the enum in its definition, that is serialized with Unity. Along with it's drawer for the Unity Editor.
using System;
using UnityEngine;
namespace EnumDictionaries
{
public abstract class EnumDictionaryBase
{
}
[Serializable]
public class EnumDictionary<TKey,TValue> : EnumDictionaryBase, ISerializationCallbackReceiver where TKey : Enum
{
[SerializeField] public TValue[] Values;
public TKey EnumType = (TKey)(object)0;
public TValue this[TKey button] => Values[(int)(object)button];
public void OnBeforeSerialize()
{
}
public void OnAfterDeserialize()
{
var keys = (TKey[])Enum.GetValues(typeof(TKey));
if(Values == null) Values = new TValue[keys.Length];
if (keys.Length > Values.Length)
{
var newValues = new TValue[keys.Length];
for (int i = 0; i < Values.Length; i++)
{
newValues[i] = Values[i];
}
Values = newValues;
}
}
}
}
using System.Collections.Generic;
using EnumDictionaries;
using UnityEditor;
using UnityEngine;
namespace Editor.EnumDictionary
{
[CustomPropertyDrawer(typeof(EnumDictionaryBase), true)]
public class EnumDictionaryDrawer : PropertyDrawer
{
private const string ValuesFieldName = "Values";
private const string EnumTypeFieldName = "EnumType";
private bool _isFoldout = true;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var valueArrayProperty = property.FindPropertyRelative(ValuesFieldName);
var enumNames = property.FindPropertyRelative(EnumTypeFieldName).enumDisplayNames;
position.height = EditorGUIUtility.singleLineHeight;
_isFoldout = EditorGUI.Foldout(position,_isFoldout,label);
position.y += EditorGUIUtility.singleLineHeight;
if (_isFoldout)
{
EditorGUI.indentLevel++;
DrawElements(ref position, valueArrayProperty, enumNames);
EditorGUI.indentLevel--;
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
var height = EditorGUIUtility.singleLineHeight;
if (_isFoldout)
{
var arrayProperty = property.FindPropertyRelative(ValuesFieldName);
var arraySize = arrayProperty.arraySize;
for (int i = 0; i < arraySize; i++)
{
var elementProperty = arrayProperty.GetArrayElementAtIndex(i);
height += EditorGUI.GetPropertyHeight(elementProperty) + EditorGUIUtility.standardVerticalSpacing;
}
}
return height;
}
private void DrawElements(ref Rect position, SerializedProperty arrayProperty, string[] enumNames)
{
var arraySize = arrayProperty.arraySize;
for (int i = 0; i < arraySize; i++)
{
var elementProperty = arrayProperty.GetArrayElementAtIndex(i);
var elementHeight = EditorGUI.GetPropertyHeight(elementProperty);
position.height = elementHeight;
EditorGUI.PropertyField(position, elementProperty, new GUIContent(enumNames[i]), true);
position.y += elementHeight + EditorGUIUtility.standardVerticalSpacing;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment