Created
February 8, 2021 16:26
-
-
Save Angeart/8c4434abfb8ab3d7e30f1801ae882d56 to your computer and use it in GitHub Desktop.
StringEnum on Unity
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 characters
| public enum ItemCategory | |
| { | |
| Consumption, | |
| Wearable, | |
| Event, | |
| } | |
| // ここ必須 | |
| [Serializable] | |
| public class ItemCategoryStringEnum : StringEnum<ItemCategory> | |
| { | |
| } | |
| public class Item : ScriptableObject | |
| { | |
| public ItemCategoryStringEnum Category = new ItemCategoryStringEnum(); | |
| } |
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 characters
| using System; | |
| using UnityEngine; | |
| namespace Utils | |
| { | |
| public class StringEnumBase | |
| { | |
| } | |
| public class StringEnum<T>: StringEnumBase, ISerializationCallbackReceiver where T : struct | |
| { | |
| [SerializeField] private string _internalValue = string.Empty; | |
| private T m_Value = default(T); | |
| public T Value { get; set; } | |
| public static StringEnum<E> Create<E>(E value) where E : struct | |
| { | |
| StringEnum<E> instance = new StringEnum<E>(); | |
| instance.m_Value = value; | |
| return instance; | |
| } | |
| public void OnBeforeSerialize() | |
| { | |
| this._internalValue = this.m_Value.ToString(); | |
| } | |
| public void OnAfterDeserialize() | |
| { | |
| if (String.IsNullOrEmpty(this._internalValue)) | |
| { | |
| this._internalValue = this.m_Value.ToString(); | |
| } | |
| this.m_Value = Utils.Enum.Parse<T>(ref _internalValue); | |
| } | |
| } | |
| } |
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 characters
| using System; | |
| using System.Linq; | |
| using System.Reflection; | |
| using Sirenix.Utilities; | |
| using UnityEditor; | |
| using UnityEngine; | |
| namespace Utils.Editor | |
| { | |
| [CustomPropertyDrawer(typeof(StringEnumBase), true)] | |
| public class StringEnumInspector : PropertyDrawer | |
| { | |
| private Type GetPropertyType(SerializedProperty property) | |
| { | |
| string[] slices = property.propertyPath.Split('.'); | |
| System.Type type = property.serializedObject.targetObject.GetType(); | |
| for(int i = 0; i < slices.Length; i++) | |
| { | |
| if (slices[i] == "Array") | |
| { | |
| i++; //skips "data[x]" | |
| type = type.GetElementType(); //gets info on array elements | |
| } | |
| //gets info on field and its type | |
| else | |
| { | |
| type = type.GetField(slices[i], BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance).FieldType; | |
| } | |
| } | |
| return type; | |
| } | |
| public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
| { | |
| label = EditorGUI.BeginProperty(position, label, property); | |
| var type = GetPropertyType(property); | |
| var valuePropertyInfo = type.GetProperty("Value"); | |
| var nameList = valuePropertyInfo != null ? System.Enum.GetNames(valuePropertyInfo.PropertyType).ToList() : Enumerable.Empty<string>().ToList(); | |
| var internalValueProperty = property.FindPropertyRelative("_internalValue"); | |
| var targetObjectType = property.serializedObject.targetObject.GetType(); | |
| var referenceObjectPropertyInfo = targetObjectType.GetMember(property.propertyPath); | |
| object referenceObject = referenceObjectPropertyInfo?.First() | |
| .GetMemberValue(property.serializedObject.targetObject); | |
| var internalValue = internalValueProperty.stringValue; | |
| if (String.IsNullOrEmpty(internalValue)) internalValue = nameList.First(); | |
| var currentIndex = nameList.FindIndex(v => v == internalValue); | |
| if (currentIndex < 0) currentIndex = 0; | |
| int index = EditorGUI.Popup(position, label.text, currentIndex, nameList.ToArray()); | |
| if (index < 0) index = 0; | |
| internalValueProperty.stringValue = nameList[index]; | |
| valuePropertyInfo?.SetValue(referenceObject, index); | |
| EditorGUI.EndProperty(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment