Решили: вершинный цвет в UI Toolkit отдаётся КАК ЕСТЬ — ручных переводов в линейное пространство в UI-коде быть не должно; цвет перед фиксацией сверяется замером пикселя, а не взглядом на скрин; значения утверждённого Максом кадра снимаются пипеткой и кладутся в токен буквально.
Почему: шейдер UITK конвертирует вершинный tint сам, как Canvas у uGUI. Наш VertexColor
делал это второй раз, и заливка приходила на экран втрое темнее заданного: rgb(44,140,146) →
rgb(6,62,69). Проверено пробой — предкомпенсированный c.gamma дал 41,133,139, то есть ровно
заданное. Отсюда вывод: конверсий должно быть ноль.
Штатной альтернативы ручному мешу нет: градиентов в USS Unity не даёт и не планирует, а градиент на
кнопке нужен. Значит вторая дорога цвета (USS → custom property → поле C# → вершина) остаётся, и
чистота — не в её удалении, а в том, что по ней нельзя молча изменить значение: одна функция на весь
UI, тождественная; у компонента нет своего цвета (дефолт Color.clear); инвариант держит тест.
Сказано: «Загугли лучше как это все делать КОРРЕКТНО. А то уже который раз! И сама не замечаешь этого!!!», «И, плиз, коммить КАЖДОЕ свое изменение при работе над UI, чтобы можно было откатиться к предыдущим вариантам», «верни кнопке именно этот цвет!» (05.08.2026).
Грабли:
- Симптом лечился трижды. Разговор начался с «кнопки слишком тёмные», и два раунда ушли на подбор оттенков — при том что ломался конвейер, а не палитра. Корень один: доверие скрину вместо замера. На тёмной гамме расхождение «задано / нарисовано» выглядит дизайнерским решением.
- Докстринг сутки предписывал ровно то, что запрещал. Комментарий от 04.08 объяснял, почему конверсия нужна, и был причиной дефекта. Комментарий не падает — поэтому инвариант такого рода обязан жить тестом.
- Живая правка полей рефлексией не переживает пересчёт стиля. Пересчёт случается не в момент
вызова
ve.style.*, а на следующем кадре, перечитывает USS и возвращает всё назад. Дважды выглядело как «агент вернул старый цвет». Лечится подпиской наCustomStyleResolvedEvent. - Кайма и заливка идут РАЗНЫМИ дорогами.
Painter2Dконвертирует сам, ручной меш — нет; в сеансе с ещё не перекомпилированным кодом это значит, что компенсацию надо давать только заливке. Одинаковая поправка обеим красит кайму мимо.
Владелец правды: Assets/_Project/Scripts/UI/Components/PlateButton.cs (VertexColor —
тождество), Assets/_Project/UI/Theme/tokens.primitives.uss (ступени patina-900/950/outline,
снятые пипеткой), скилл xgaida-x-nixi-uitk (разделы «Цвет: одна дорога на экран» и «Коммитить
каждое изменение UI»).