Unity странное поведение UI toolkit при генерации property drawer

Столкнулся со странным поведением UI Toolkit в редакторе при отрисовке PropertyDrawer(PD). В целом рисуется все изначально правильно, то есть генерация самого контрола через код проходит нормально. У меня рядом с текстовым полем есть несколько кнопок для управления выбором доступных значений и их редактированием. Проверяю в отладке, вижу что в коде все нормально проставляется как в ui, так и в Serialized property значение сохраняется. Для работы контрола пришлось обходиться без биндинга к свойству, поэтому изменяю их по отдельности в коде, apply modify к сериализованному объекту применяю и вроде все нормально. Странно ведет себя именно визуальная часть, поскольку то пропадает метка у контрола, то при смене исчезает значение в текстовом поле... Причем клики по полям MonoBehaivour (как этому так и другим) периодически переключают это состояние, то какую то левую метку подставляет, то значение в текстовом поле начинает показывать... то начинает показывать метки других полей этого класса... Бывает изменяет соседние поля. Доходит до того что вообще все тексты в контролах чистятся, вижу только разметку разными контролами в интерфейсе.

В самом PD создание метки только при генерации контрола задается и в дальнейшем не изменяется, как и значение, которое успешно сохраняется. Биндинги не использую, обхожусь лишь отслеживанием изменения свойством и событием на изменение значения.

Такое впечатление как будто редактор класса начинает пересоздавать интерфейс и вылетает с ошибками... Но на сколько я понимаю суть UI Toolkit в его основу заложено именно разовое создание интерфейса и в дальнейшем его обновление лишь при возникновении отдельных событий как действие пользователя или изменение данных в источнике по той или иной привязке... А тут ощущение что на каждый клик по интерфейсу он пытается его пересоздать...

Сталкивался ли кто с подобным, как решали?


Ответы (2 шт):

Автор решения: Yaroslav

Нет, это не суть UI Toolkit, так все систему UI устроены. Каждый Canvas Renderer, что висит на всех Image, RawImage или Text в базовом UI, делает repaint только по факту изменения.

Что касается описанных проблем, насколько я могу предположить, ты пытаешься хранить ссылочные значения в полях класса, ожидая, что для каждого экземпляра твоего MonoBehaivour создаётся по экземпляру PropertyDrawer, но если я правильно помню, то это не так и один Drawer может обрабатывать множество объектов соответствующего типа, существуя лишь до тех пор, пока отображается зотя бы один объект данного типа. Попробуй поэксперементировать генерируя случайное число в PropertyDrawer, если оно ещё не сгенерированно и выводить его в лог, так ты немного поймёшь что и в каких случаях на самом деле происходит.

Хранить SerializedProperty вообще бесполезно, у него короткий жизненный цикл. То есть твой интерфейс пытается отобразить свойства, которые уже не привязаны к объекту, потому что тот цикл сериализации и десириализации объекта уже закончен и используется новый, а в текущий момент вообще обрабатывать совсем другой объект. Так-же SerializedProperty это не какое-то конкретное свойство, а IEnumerable всех свойств объекта и свойств свойств, которые обрабатываются по очереди и обращаясь к одному и тому-же SerializedProperty, но в разный момент, можно получить разные поля или самому переключить текущее свойство на следующий с помощью .Next(). То есть поле Vector2 pos это не одно свойство, а три: Vector2 pos, float x и float y идущих по порядку в одном списке, который хранит SerializedProperty.

Сам в своё время, когда с этим игрался, ошибался в предположениях и далеко не сразу удавалось понять как я должен это обрабатывать и что я вообще обрабатываю. Не совсем easy to use в отличает от UI из коробки. С этим нужно долго сидеть, что бы этим овладеть.

Проще говоря под капотом там не иерархия объектах в камне, а бурный поток на конвейере, где объекты создаются и уничтожаются и нет ничего лишнего на момент времени, что направлено на лёгкость и быстродействие с множеством возможностей.

→ Ссылка
Автор решения: KingPeas

Разобрался с причиной странного поведения PropertyDrawer. При обработке контекстного меню, а также генерации визуального элемента выполнялась операция по обновлению текущего состояния контрола. Так вот во время этой операции возникала ошибка которая видимо и нарушала работу по отрисовке поля в редакторе. Причем речь идет про отрисовку PD в другом отображаемом в редакторе скрипте, а в итоге лихорадило весь редактор.

→ Ссылка