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

3

假设我们有以下枚举类型:

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为空。
我还尝试替换


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

使用

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

我试图给它一个“初始值”,但是当我按下播放时,值A1会覆盖所选的值。有什么想法吗?

1个回答

3

我通过添加一个占位符字段来存储枚举值,解决了这个问题。

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

非常棒的解决方案。正是我所寻找的! - incutonez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接