Получение значений из MultiFloatField в Unity - PullRequest
0 голосов
/ 10 ноября 2018

Я копался в подобных вопросах, но ни один из них, похоже, не задавался, поэтому ради потенциальных пользователей Google с такой же проблемой (особенно людей, которые новички в Unity / Editor scripting / C #), я считаю этот вопрос должен существовать.

Я писал ящик пользовательских свойств для класса, но по какой-то причине ни одно из отдельных полей не было кликабельным. Я использовал отдельные PropertyField s для переменных с плавающей точкой, но решил попробовать и использовать MultiFloatField, чтобы посмотреть, поможет ли это. Вот что я сделал:

var fwd = property.FindPropertyRelative("Forwards").floatValue;
var bwd = property.FindPropertyRelative("Backwards").floatValue;
var left = property.FindPropertyRelative("StrafeLeft").floatValue;
var right = property.FindPropertyRelative("StrafeRight").floatValue;
EditorGUI.MultiFloatField(position, new [] {"F", "B", "L", "R"}.Select(x => new GUIContent(x)).ToArray(), new [] {fwd, bwd, left, right});

Не может жить без LINQ. Однако, пытаясь изменить значения, они сразу же сбрасывали себя до того, что было их первоначальным значением. Учитывая, что метод MultiFloatField ничего не возвращает, как именно вы извлекаете из него отредактированные значения?

1 Ответ

0 голосов
/ 10 ноября 2018

Ответ обманчиво прост: Массивы в C # являются ссылочными типами , что означает, что редактирование чего-либо в массиве сохраняет отредактированное значение. Чтобы проиллюстрировать, как правильно использовать MultiFloatField, вот пример из ссылки Unity C # :

    // Make an X, Y & Z field for entering a [[Vector3]].
    private static Vector3 Vector3Field(Rect position, Vector3 value)
    {
        s_Vector3Floats[0] = value.x;
        s_Vector3Floats[1] = value.y;
        s_Vector3Floats[2] = value.z;
        position.height = kSingleLineHeight;
        BeginChangeCheck();
        MultiFloatField(position, s_XYZLabels, s_Vector3Floats);
        if (EndChangeCheck())
        {
            value.x = s_Vector3Floats[0];
            value.y = s_Vector3Floats[1];
            value.z = s_Vector3Floats[2];
        }
        return value;
    }

Как мы видим, есть массив (называемый s_Vector3Floats), который передается в MultiFloatField; измененные значения считываются непосредственно из того же массива.

Ergo, в приведенном выше примере проблема заключается в том, что мы каждый раз создаем новый массив. Лучший (и работающий!) Способ сделать это будет следующим:

    var fwd = property.FindPropertyRelative("Forwards");
    var bwd = property.FindPropertyRelative("Backwards");
    var left = property.FindPropertyRelative("StrafeLeft");
    var right = property.FindPropertyRelative("StrafeRight");
    var array = new[] {fwd.floatValue, bwd.floatValue, left.floatValue, right.floatValue};
    EditorGUI.MultiFloatField(position, new [] {"F", "B", "L", "R"}.Select(x => new GUIContent(x)).ToArray(), array);
    fwd.floatValue = array[0];
    bwd.floatValue = array[1];
    left.floatValue = array[2];
    right.floatValue = array[3];

И дополнительный бонус: если вы используете Foldout и не можете нажать на свое содержимое, это, вероятно, потому что вы даете Foldout Rect, который слишком далеко большой . Будьте осторожны с вашими приказами. Они, в отличие от массивов, являются типами значений.

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