Пользовательский редактор сценариев Unity C # с динамическим полем Enum - PullRequest
1 голос
/ 09 октября 2019

Допустим, у нас есть следующие Enums

public enum Section
{
    A,
    B
}

public enum SectionA
{
    A1,
    A2,
    A3
}

public enum SectionB
{
    B1,
    B2,
    B3
}

Я хотел бы создать скрипт с двумя открытыми полями Enum, с выбираемыми значениями в качестве выпадающих списков из Unity Editor. Первый служит для выбора раздела (A или B), а второй должен быть Enum типа 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 переопределяет выбранное. когда я нажимаю Play. Есть идеи?

1 Ответ

0 голосов
/ 09 октября 2019

Я исправил это, добавив поле-заполнитель для хранения значения перечисления.

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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...