Unity Custom Editor Когда я создаю 2D-массив, я переключаю их, и они не могут быть нажаты - PullRequest
0 голосов
/ 02 апреля 2020

Я склоняюсь к пользовательскому редактору, и у меня проблема с SerializeObject, я создаю переключатели 2D-массивов и обнаружил, что все они не работают, когда я нажимаю на них. Я пытаюсь сделать все, что могу, но все равно не работает помогите мне?

public override void OnInspectorGUI()
{
    EditorGUI.BeginChangeCheck();
    serializedObject.Update();

    for (int i = 0; i < 9; i++)
    {
        EditorGUILayout.BeginHorizontal();
        GUIStyle s1 = new GUIStyle();
        s1.padding.top = 20;
        s1.padding.left = 2;
        if (i == 0)
        {
            EditorGUILayout.LabelField("Site " + (i+1).ToString(), s1, GUILayout.MaxWidth(40));
        }
        else
        {
            EditorGUILayout.LabelField("Site " + (i+1).ToString(), GUILayout.MaxWidth(40));
        }
        for (int j = 0; j < 9; j++)
        {
            SerializedProperty r = TheNewList.GetArrayElementAtIndex(i).FindPropertyRelative("road").GetArrayElementAtIndex(j);
            SerializedProperty w = TheNewList.GetArrayElementAtIndex(i).FindPropertyRelative("weight").GetArrayElementAtIndex(j);
            serializedObject.Update();
            EditorGUILayout.BeginVertical();
            if (i == 0)
            {
                EditorGUILayout.LabelField((j+1).ToString(), GUILayout.MaxWidth(10));
            }
            r.boolValue = EditorGUILayout.Toggle(m_Target.roadEditor[i].road[j]);
            if (setWeight)
            {
                w.intValue = (int)EditorGUILayout.IntField((int)m_Target.roadEditor[i].weight[j], GUILayout.MaxWidth(21));
            }
            EditorGUILayout.EndVertical();
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();
    }
    serializedObject.ApplyModifiedProperties();
}

}

1 Ответ

0 голосов
/ 02 апреля 2020

Удалите дополнительные

serializedObject.Update();

в for l oop!

Это загружает текущие значения в сериализованные свойства на каждой итерации. Это означает, что даже если вы измените значение, которое не является последним переключателем, текущее значение будет перезагружено до того, как редактор достигнет строки

serializedObject.ApplyModifiedProperties();

Общее примечание: Do not mix SerializedProperties и прямой доступ к полям вашего класса через target!

Лучше вообще не использовать target ... есть некоторые исключения, когда вы хотите вызвать метод или что-то, но в обычно придерживайтесь только SerializedProperty!

В вашем случае вы можете просто сделать

public override void OnInspectorGUI()
{
    // A little bonus see below
    DrawScriptField();

    // Note: you only want to begin a change check if you also end it somewhere
    // with the according if(EditorGUI.EndChangeCheck()) { ... } block
    //EditorGUI.BeginchangeCheck();

    // This you only want to do once for each OnInspectorGUI iteration
    serializedObject.Update();

    for (var i = 0; i < 9; i++)
    {
        // Get all these only ONCE instead of in every iteration of the inner loop
        var element = TheNewList.GetArrayElementAtIndex(i);
        var road = element.FindPropertyRelative("road");
        var weight = element.FindPropertyRelative("weight");

        // I like to wrap my code blocks in { } when possible in order to keep 
        // it a bit cleaner. Does only owrk ofcourse if you don't declare variables
        // you need later. On this way I don't forget to end the draw groups
        EditorGUILayout.BeginHorizontal();
        {
            var s1 = new GUIStyle { padding = { top = 20, left = 2 } };

            if (i == 0)
            {
                EditorGUILayout.LabelField("Site " + (i + 1), s1, GUILayout.MaxWidth(40));
            }
            else
            {
                EditorGUILayout.LabelField("Site " + (i + 1), GUILayout.MaxWidth(40));
            }

            for (var j = 0; j < 9; j++)
            {
                var r = road.GetArrayElementAtIndex(j);
                var w = weight.GetArrayElementAtIndex(j);

                EditorGUILayout.BeginVertical();
                {
                    if (i == 0)
                    {
                        EditorGUILayout.LabelField((j + 1).ToString(), GUILayout.MaxWidth(10));
                    }

                    // By simply using PropertyField the Inspector automatically 
                    // - choses the correct drawer according to the property type
                    // - reads and writes the value to the serializedproperty and handles undo/redo etc
                    EditorGUILayout.PropertyField(r, GUIContent.none, GUILayout.MaxWidth(10));

                    if (setWeight)
                    {
                        EditorGUILayout.PropertyField(w, GUIContent.none, GUILayout.MaxWidth(21));
                    }
                }
                EditorGUILayout.EndVertical();
            }
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();
    }
    serializedObject.ApplyModifiedProperties();
}

// This you get as a little bonus from my side ;)
private void DrawScriptField()
{
    EditorGUI.BeginDisabledGroup(true);
    EditorGUILayout.ObjectField("Script", MonoScript.FromMonoBehaviour((YOURSCRIPTTYPE)target), typeof(YOURSCRIPTTYPE), false);
    EditorGUI.EndDisabledGroup();

    EditorGUILayout.Space();
}

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...