3

Let's say we have the following Enums

public enum Section
{
    A,
    B
}

public enum SectionA
{
    A1,
    A2,
    A3
}

public enum SectionB
{
    B1,
    B2,
    B3
}

I would like to make a script with two public Enum fields, with selectable values as dropdowns from the Unity Editor. The first one serves to select the Section (A or B), while the second one should be an Enum of type SectionA or SectionB depending what the selected value on the first field is.

I made the following scripts for this:

public class Item : MonoBehaviour
{
    [HideInInspector]
    public Section Section;

    [HideInInspector]
    public System.Enum Value;
}


[CustomEditor(typeof(Item))]
public class ItemEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        Item item = target as Item;

        item.Section = (Section)EditorGUILayout.EnumPopup(item.Section);

        switch (item.Section)
        {
            case Section.A:
                item.Value = (SectionA)EditorGUILayout.EnumPopup(item.Value);
                break;
            case Section.B:
                item.Value = (SectionB)EditorGUILayout.EnumPopup(item.Value);
                break;
        }
    }
}

But it triggers an Exception stating that item.Value is null.

I also tried replacing

item.Value = (SectionA)EditorGUILayout.EnumPopup(item.Value);

with

item.Value = (SectionA)EditorGUILayout.EnumPopup(item.Value ?? SectionA.A1);

to try to give it an "Initial Value" but then the value A1 overrides the selected one when I press Play. Any ideas?

1 Answer 1

3

I fixed it by adding a placeholder field to store the enum value.

public class Item : MonoBehaviour
{
    [HideInInspector]
    public Section Section;

    [HideInInspector]
    public System.Enum Value;

    [HideInInspector]
    public SectionA a;

    [HideInInspector]
    public SectionB b;
}

switch (item.Section)
{
    case Section.A:
        item.Value = EditorGUILayout.EnumPopup(item.a = (SectionA)(item.Value ?? item.a));
        break;
    case Section.B:
        item.Value = EditorGUILayout.EnumPopup(item.b = (SectionB)(item.Value ?? item.b));
        break;
}

The previous solution often fails to save values when you switch scenes. This works properly.

public class Item : MonoBehaviour
{ 
    public Section section;
    public SectionA sectionA;
    public SectionB sectionB;

    public System.Enum Value
    {
        get
        {
            switch(section)
            {
                case Section.A:
                    return sectionA;
                case Section.B:
                    return sectionB;
                default:
                    return null;
            }
        }
    }
}

[CustomEditor(typeof(Item))]
public class ItemEditor : Editor
{
    SerializedProperty section;
    SerializedProperty sectionA;
    SerializedProperty sectionB;

    void OnEnable()
    {
        section = serializedObject.FindProperty("section");
        sectionA = serializedObject.FindProperty("sectionA");
        sectionB = serializedObject.FindProperty("sectionB");
    }

    public override void OnInspectorGUI()
    {        
        serializedObject.Update();
        EditorGUILayout.PropertyField(section);
        switch ((Section)section.enumValueIndex)
        {
            case Section.A:
                EditorGUILayout.PropertyField(sectionA);
                break;
            case Section.B:
                EditorGUILayout.PropertyField(sectionB);
                break;
        }   
        serializedObject.ApplyModifiedProperties();
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Very cool solution. Exactly what I was looking for!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.