Не понимаю как работает отрисовка полей и получение значений, введенных пользователем в Unity 3D.
Вот пример из документации:
// Editor Script that clones the selected GameObject a number of times.
class EditorGUILayoutIntField extends EditorWindow {
var clones : int = 1;
@MenuItem("Examples/Clone Object")
static function Init() {
var window = GetWindow(EditorGUILayoutIntField);
window.Show();
}
function OnGUI() {
clones = EditorGUILayout.IntField("Number of clones:", clones);
if(GUILayout.Button("Clone!"))
for(var i = 0; i < clones; i++)
Instantiate(Selection.activeGameObject, Vector3.zero, Quaternion.identity);
}
}
Не понятно как работает вот эта строчка:
clones = EditorGUILayout.IntField("Number of clones:", clones);
Она вроде как и отрисовывает поле и возвращает значение, введенное пользователем. Объясните пожалуйста.
Ответ
Да, подобные поля в EditorGUI возвращают значение, введенное пользователем.
Логически все просто понять: для того, чтобы установить значение полю, достаточно ему передать какое-то значение из переменной или написать вручную. Однако, в таком случае, по факту, это поле будет read-only, т.к. через инспектор нельзя будет никаким образом изменить значение в этом поле. Что и логично, ведь OnGUI работает несколько раз в секунду, а в поле мы можем написать EditorGUILayout.IntField("Number of clones:", 100500);, в результате чего несколько раз в секунду перерисовывается поле с константным значением.
Для чего пишут так: clones = EditorGUILayout.IntField("Number of clones:", clones);? Чтобы сделать, так сказать сообщение между переменной и значением, которое ввел пользователь.
Получается некий бесконечный круг:
В поле заносится значение переменной.
Пользователь меняет значение в поле
Это значение передается обратно в переменную, чтобы:
После очередного обновления OnGUI значение этой самой переменной попало опять в IntField
Тем самым мы сможем влиять на переменную через поле. А поле отображать реальное значение переменной на данный момент
Если не хотите, чтобы значение переменно через поле изменялось просто пишите
EditorGUILayout.IntField("Number of clones:", clones); без clones =
Может логичным показаться вопрос, почему не сделать передачу по ссылке? Но не все значения так пишутся. Некоторые не возвращают значение в переменную, чтоб поле оставалось как раз read-only и при этом значение переменной нельзя было через поле изменить.
Может показаться что разрабам было бы логичнее сделать что-то типа того EditorGUILayout.IntField("Number of clones:", clones, true/false); где true/false задает передавать по значение ссылке или нет, но, думаю, это сложнее по логике реализовать, чем просто вернуть значение. Возможно еще по каким-то причинам.
Комментариев нет:
Отправить комментарий