带有动态枚举字段的自定义Unity C#脚本编辑器

带有动态枚举字段的自定义Unity C#脚本编辑器,c#,unity3d,enums,C#,Unity3d,Enums,假设我们有以下枚举 public enum Section { A, B } public enum SectionA { A1, A2, A3 } public enum SectionB { B1, B2, B3 } 我想制作一个包含两个公共枚举字段的脚本,其中包含Unity编辑器中的下拉列表中的可选值。第一个用于选择节(A或B),而第二个应为SectionA或SectionB类型的枚举,具体取决于第一个字段上选择的值 我

假设我们有以下枚举

public enum Section
{
    A,
    B
}

public enum SectionA
{
    A1,
    A2,
    A3
}

public enum SectionB
{
    B1,
    B2,
    B3
}
我想制作一个包含两个公共枚举字段的脚本,其中包含Unity编辑器中的下拉列表中的可选值。第一个用于选择节(A或B),而第二个应为SectionA或SectionB类型的枚举,具体取决于第一个字段上选择的值

我为此制作了以下脚本:

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;
        }
    }
}
但它会触发一个异常,声明
item.Value
为null

我也试着换了

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

尝试给它一个“初始值”,但当我按Play时,值
A1
会覆盖所选值。有什么想法吗?

我通过添加一个占位符字段来存储枚举值来修复它

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;
}

在切换场景时,以前的解决方案通常无法保存值。这工作正常

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();
    }
}

非常酷的解决方案。正是我要找的!
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();
    }
}