Решили: ни один PanelSettings в Assets/_Project не имеет права на clearColor — непрозрачный
фон даёт камера своей сцены. Инвариант держит тест PanelSettingsTests, потому что нарушить его
можно в ассете dev-стенда, а сломается при этом кадр игры.
Почему: «иногда при запуске сцены просто серый экран» оказался не гонкой бута и не потерянной
подпиской: пустая панель UI-стенда очищала весь буфер своим серым (0.060, 0.060, 0.070) и стирала
кадр целиком — мир, интерфейс, всё. Второй кандидат, DisableDomainReload в Enter Play Mode, тут ни
при чём, хотя выглядел убедительно и остаётся отдельным риском.
Грабли:
- Панель UITK принадлежит АССЕТУ, а не сцене.
PreviewPanelSettingsживёт вUiPreview.unity, которая в игре не загружается — но стоит ассету попасть в память (открыли стенд, кликнули в Project, прошлись скриптом поFindAssets("t:PanelSettings")), его рантайм-панель регистрируется глобально и рисуется в любой сцене. Проверять «кто ссылается на ассет» здесь бесполезно: ссылок нет ни одной, а панель есть. - «Иногда» объяснялось приоритетом. У игровой панели и панели стенда одинаковый
sortingPriority, поэтому порядок отрисовки решает порядок регистрации: разбудили стенд раньше игры — кадр цел, позже — стёрт. Отсюда недетерминизм, из-за которого баг месяцами читался как «показалось». - Цвет назвал виновника точнее логов. Серый на экране был 45454B, а
colorClearValueстенда — (0.060, 0.060, 0.070): те же числа, переведённые из линейного в sRGB. Логи при этом были безупречны — бут проходил, экран строился, дерево элементов на месте. - Токен
--gm-color-console-surfaceбыл холодным —rgba(10, 12, 14), синева среди тёплой палитры. Прозрачность разрешено задавать rgba напрямую (как у скрима), но оттенок обязан лежать на рампе ink: R > G > B.
Владелец правды: тест PanelSettingsTests, ассет UI/Dev/PreviewPanelSettings.asset,
токен в UI/Theme/tokens.semantic.uss.