-
-
Save mattdevv/a3275cbd3ada72530d432db79ade6d18 to your computer and use it in GitHub Desktop.
Revisions
-
mattdevv revised this gist
Aug 21, 2025 . 1 changed file with 81 additions and 44 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,36 +1,39 @@ using System; using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif [Serializable] public class EnumArray<TEnum, TData> : IEnumerable<TData>, ISerializationCallbackReceiver where TEnum : Enum { public static readonly int s_Length; [SerializeField] private TData[] _values; public int Length => s_Length; static EnumArray() { var names = Enum.GetNames(typeof(TEnum)); s_Length = names.Length; #if UNITY_EDITOR EnumArrayDrawer.Names[typeof(TEnum)] = names; if (Enum.GetUnderlyingType(typeof(TEnum)) != typeof(int)) Debug.LogWarning($"EnumArray should not be used with Enum type {typeof(TEnum)} as it doesn't derive from int"); var values = Enum.GetValues(typeof(TEnum)) as int[]; Array.Sort(values, (i0, i1) => i0 - i1); if (values[0] != 0) Debug.LogWarning($"EnumArray should not be used with Enum type {typeof(TEnum)} as it doesn't start from 0"); for (int i = 1; i < values.Length; i++) { if (values[i] != values[i - 1] + 1) { Debug.LogWarning($"EnumArray should not be used with Enum type {typeof(TEnum)} as it contains a gap in enums"); break; } } @@ -39,21 +42,32 @@ static EnumArray() public EnumArray() { _values = new TData[s_Length]; } public ref TData this[TEnum e] { get => ref _values[e.GetHashCode()]; } public ref TData this[int i] { get => ref _values[i]; } public IEnumerator<TData> GetEnumerator() { return ((IEnumerable<TData>) _values).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void OnAfterDeserialize() { // required check in case array was serialized when Enumerator class had a different number of elements if (_values.Length != s_Length) Array.Resize(ref _values, s_Length); } @@ -62,14 +76,13 @@ public void OnBeforeSerialize() { } } #if UNITY_EDITOR [CustomPropertyDrawer(typeof(EnumArray<,>), true)] public class EnumArrayDrawer : PropertyDrawer { private const float Padding = 4; private const float Spacing = 2; public static readonly Dictionary<Type, string[]> Names = new(); private Type _type; @@ -78,16 +91,16 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent if (_type == null) _type = fieldInfo.FieldType.GenericTypeArguments[0]; property.Next(true); // this will be the array // header + top/bottom padding float height = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; if (property.isExpanded) { int arraySize = property.arraySize; // spacing between array elements height += arraySize * Spacing + 2 * Padding; // get each array element height for (int i = 0; i < arraySize; i++) @@ -99,38 +112,62 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { //var enumArrayProperty = property. var header = position; header.height = EditorGUIUtility.singleLineHeight; header.width -= EditorGUIUtility.standardVerticalSpacing * 3; bool expanded = EditorGUI.BeginFoldoutHeaderGroup(header, property.isExpanded, label); property.isExpanded = expanded; if (property.hasMultipleDifferentValues == false) { // only use header as a property if array has same values EditorGUI.BeginProperty(header, label, property); EditorGUI.EndProperty(); } property.Next(true); // this will be the array if (expanded) { if (Event.current.type == EventType.Repaint) { Rect background = position; background.height -= EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing; background.y += EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing; EditorStyles.helpBox.Draw(background, false, false, false, false); } position.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing * 4; var labels = Names[_type]; for (int i = 0; i < property.arraySize; i++) { Rect propertyRect = position; var serializedElement = property.GetArrayElementAtIndex(i); propertyRect.height = EditorGUI.GetPropertyHeight(serializedElement); label.text = labels[i]; if (propertyRect.Contains(Event.current.mousePosition)) { Color col = EditorGUIUtility.isProSkin ? new Color32(80, 80, 80, 255) : new Color32 (210, 210, 210, 255); EditorGUI.DrawRect(propertyRect, col); } propertyRect.x += 6 * EditorGUIUtility.standardVerticalSpacing; propertyRect.width -= 9 * EditorGUIUtility.standardVerticalSpacing; EditorGUI.PropertyField(propertyRect, serializedElement, label, true); position.y += propertyRect.height + Spacing; } } EditorGUI.EndFoldoutHeaderGroup(); } } #endif -
mattdevv revised this gist
Jan 3, 2025 . 1 changed file with 6 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -42,16 +42,14 @@ public EnumArray() _values = new T[s_Length]; } public ref T this[E e] { get => ref _values[e.GetHashCode()]; } public ref T this[int i] { get => ref _values[i]; } public void OnAfterDeserialize() @@ -97,9 +95,6 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent } return height; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) @@ -128,10 +123,10 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten for (int i = 0; i < property.arraySize; i++) { var serializedElement = property.GetArrayElementAtIndex(i); position.height = EditorGUI.GetPropertyHeight(serializedElement); label.text = labels[i]; GUI.Box(position, GUIContent.none); EditorGUI.PropertyField(position, serializedElement, label, true); position.y += position.height + Spacing; -
mattdevv revised this gist
Jan 3, 2025 . 1 changed file with 35 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -81,35 +81,60 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent _type = fieldInfo.FieldType.GenericTypeArguments[0]; property.Next(true); // header + top/bottom padding float height = EditorGUIUtility.singleLineHeight + 2 * Padding; if (open) { int arraySize = property.arraySize; // spacing between array elements height += arraySize * Spacing; // get each array element height for (int i = 0; i < arraySize; i++) height += EditorGUI.GetPropertyHeight(property.GetArrayElementAtIndex(i)); } return height; // WRONG: assumes all array elements are single line height //return (EditorGUIUtility.singleLineHeight + Spacing) * ((open ? property.arraySize : 0) + 1) + Padding * 2; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (Event.current.type == EventType.Repaint) EditorStyles.helpBox.Draw(position, false, false, false, false); position.height = EditorGUIUtility.singleLineHeight; position.y += Padding; position.x += Padding * 4; position.width -= Padding * 8; var style = new GUIStyle(EditorStyles.foldout); style.fontStyle = FontStyle.Bold; open = EditorGUI.Foldout(position, open, label, style); if (!open) return; position.y += EditorGUIUtility.singleLineHeight + Spacing; position.x += Padding * 2; position.width -= Padding * 4; property.Next(true); var labels = Names[_type]; for (int i = 0; i < property.arraySize; i++) { var serializedElement = property.GetArrayElementAtIndex(i); position.height = EditorGUI.GetPropertyHeight(serializedElement); label.text = labels[i]; EditorGUI.PropertyField(position, serializedElement, label, true); position.y += position.height + Spacing; } } } -
mattdevv revised this gist
Dec 13, 2024 . 1 changed file with 28 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,8 +16,24 @@ static EnumArray() { var names = Enum.GetNames(typeof(E)); s_Length = names.Length; #if UNITY_EDITOR EnumArrayDrawer.Names[typeof(E)] = names; if (Enum.GetUnderlyingType(typeof(E)) != typeof(int)) Debug.LogWarning($"EnumArray should not be used with Enum type {typeof(E)} as it doesn't derive from int"); var values = Enum.GetValues(typeof(E)) as int[]; Array.Sort(values, (i0, i1) => i0 - i1); if (values[0] != 0) Debug.LogWarning($"EnumArray should not be used with Enum type {typeof(E)} as it doesn't start from 0"); for (int i = 1; i < values.Length; i++) { if (values[i] != values[i - 1] + 1) { Debug.LogWarning($"EnumArray should not be used with Enum type {typeof(E)} as it contains a gap in enums"); break; } } #endif } @@ -53,6 +69,7 @@ public class EnumArrayDrawer : PropertyDrawer { private const float Padding = 4; private const float Spacing = 2; private bool open = false; public static readonly System.Collections.Generic.Dictionary<Type, string[]> Names = new(); @@ -64,19 +81,26 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent _type = fieldInfo.FieldType.GenericTypeArguments[0]; property.Next(true); return (EditorGUIUtility.singleLineHeight + Spacing) * ((open ? property.arraySize : 0) + 1) + Padding * 2; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (Event.current.type == EventType.Repaint) EditorStyles.helpBox.Draw(position, false, false, false, false); position.height = EditorGUIUtility.singleLineHeight; position.y += Padding; position.x += Padding * 4; position.width -= Padding * 8; open = EditorGUI.Foldout(position, open, label, EditorStyles.foldout); position.x -= Padding * 2; position.width += Padding * 4; if (!open) return; property.Next(true); var step = EditorGUIUtility.singleLineHeight + Spacing; -
a-gruzdev revised this gist
Dec 13, 2024 . No changes.There are no files selected for viewing
-
a-gruzdev revised this gist
Dec 13, 2024 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -38,7 +38,6 @@ public T this[int i] set => _values[i] = value; } public void OnAfterDeserialize() { if (_values.Length != s_Length) -
a-gruzdev created this gist
Dec 13, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,93 @@ using System; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif [Serializable] public class EnumArray<E, T> : ISerializationCallbackReceiver where E : Enum { public static readonly int s_Length; [SerializeField] private T[] _values; public int Length => s_Length; static EnumArray() { var names = Enum.GetNames(typeof(E)); s_Length = names.Length; #if UNITY_EDITOR EnumArrayDrawer.Names[typeof(E)] = names; #endif } public EnumArray() { _values = new T[s_Length]; } public T this[E e] { get => _values[e.GetHashCode()]; set => _values[e.GetHashCode()] = value; } public T this[int i] { get => _values[i]; set => _values[i] = value; } public void OnAfterDeserialize() { if (_values.Length != s_Length) Array.Resize(ref _values, s_Length); } public void OnBeforeSerialize() { } } #if UNITY_EDITOR [CustomPropertyDrawer(typeof(EnumArray<,>))] public class EnumArrayDrawer : PropertyDrawer { private const float Padding = 4; private const float Spacing = 2; public static readonly System.Collections.Generic.Dictionary<Type, string[]> Names = new(); private Type _type; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { if (_type == null) _type = fieldInfo.FieldType.GenericTypeArguments[0]; property.Next(true); return (EditorGUIUtility.singleLineHeight + Spacing) * (property.arraySize + 1) + Padding * 2; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (Event.current.type == EventType.Repaint) EditorStyles.helpBox.Draw(position, false, false, false, false); position.height = EditorGUIUtility.singleLineHeight; position.y += Padding; position.x += Padding; position.width -= Padding * 2; GUI.Label(position, label, EditorStyles.boldLabel); property.Next(true); var step = EditorGUIUtility.singleLineHeight + Spacing; var labels = Names[_type]; for (int i = 0; i < property.arraySize; i++) { position.y += step; label.text = labels[i]; EditorGUI.PropertyField(position, property.GetArrayElementAtIndex(i), label); } } } #endif