In my current project I have a damageType enum and I want different races (ScriptableObject) to have different resistances/vulnerabilities to each damageType. I don’t want to hardcode a variable for each damageType in case I add/remove types, so I thought I’d be clever and use a custom editor to create a slider for each type in the enum and store the respective value in an array. I anticipated a problem, in that the array-Length does not get updated it the enum changes, but I don’t know a solution to this.
Does anyone here have a suggestion how to do it (better)?
(Dictionary does not work, since it doesn’t get serialized)
But if you don’t want to do that, what about this:
public enum DamageType { Fire, Lightning, Ice }
public class Race : ScriptableObject {
[Serializable]
public DamageRating {
public string damageTypeName;
public float value;
}
public DamageRating[] damageRatings;
}
[CustomEditor(typeof(Race), true)]
public RaceEditor : Editor {
public override void OnInspectorGUI() {
serializedObject.Update();
string[] enumNames = Enum.GetNames(typeof(DamageType));
foreach (var enumName in enumNames) {
DrawDamageRating(enumName);
}
serializedObject.ApplyModifiedProperties();
}
void DrawDamageRating(string enumName) {
SerializedProperty damageRatingProperty = GetDamageRatingProperty(enumName);
SerializedProperty valueProperty = damageRatingProperty.FindPropertyRelative("value");
EditorGUILayout.PropertyField(valueProperty, new GUIContent(enumName));
}
SerializedProperty GetDamageRatingProperty(string enumName) {
SerializedProperty damageRatingsProperty = serializedObject.FindProperty("damageRatings");
for (int i = 0; i < damageRatingsProperty.arraySize; i++) {
var damageRatingProperty = damageRatingsProperty.GetElementAtIndex(i);
var nameProperty = damageRatingProperty.FindPropertyRelative("damageTypeName");
if (string.Equals(enumName, nameProperty.stringValue)) {
return damageRatingProperty;
}
}
// Didn't find in array, so add it:
damageRatingsProperty.arraySize++;
var damageRatingProperty = damageRatingsProperty.GetElementAtIndex(damageRatingsProperty.arraySize - 1);
damageRatingProperty.FindPropertyRelative("damageTypeName").stringValue = enumName;
return damageRatingProperty;
}
}
I just typed this into the post, so no guarantees against typos.
Also, you might want to clean up obsolete entries in case you end up deleting enum values.