【问题标题】:Custom Unity C# Script Editor with dynamic Enum Field具有动态枚举字段的自定义 Unity C# 脚本编辑器
【发布时间】:2019-10-09 15:29:07
【问题描述】:

假设我们有以下枚举

public enum Section
{
    A,
    B
}

public enum SectionA
{
    A1,
    A2,
    A3
}

public enum SectionB
{
    B1,
    B2,
    B3
}

我想制作一个包含两个公共枚举字段的脚本,其中可选择值作为 Unity 编辑器的下拉菜单。第一个用于选择 Section(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 的值会覆盖选定的值。有什么想法吗?

【问题讨论】:

    标签: c# unity3d enums


    【解决方案1】:

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

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

    【讨论】:

    • 非常酷的解决方案。正是我想要的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2022-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多