# 16. Тени
Table of Contents
16. Тени
Цель
Добавить объём и отделение слоёв интерфейса от фона без тяжёлых текстур: проект уже построен на Panel и StyleBoxFlat, поэтому логично использовать встроенные поля shadow_color, shadow_size и shadow_offset там, где элемент выглядит «липким» к звёздному небу.
Описание выполненной работы
Почему именно StyleBoxFlat, а не отдельные спрайты теней
В Godot 4 для Control узлов самый предсказуемый способ получить мягкую тень без дополнительных текстур и без включения сложных CanvasLayer эффектов — параметры у StyleBoxFlat. Они работают при любом масштабе интерфейса (режим canvas_items stretch у проекта), корректно обрезаются скруглениями corner_radius и не требуют править код game_board.gd: всё остаётся в .tscn и шейдере планеты.
Отдельные DropShadow через ColorRect или дублирование узлов под каждую кнопку удорожили бы сцену и усложнили анимации масштаба клеток из шага 15 — тень StyleBox масштабируется вместе с Panel.
Ячейки поля (cell_view.tscn)
Стиль StyleBoxFlat_cell дополнен полями:
shadow_colorс умеренной альфой (около0.42) на чёрном, чтобы на градиентном космическом фоне тень не давала серую «кашу»;shadow_sizeпорядка5пикселей для мобильного DPI;shadow_offsetсо смещением вниз (Vector2(1, 4)), чтобы свет всё ещё читался как «сверху-слева», согласованный с освещением вplanet_ball.gdshader.
При удалении линии масштаб и альфа клетки анимируются шагом 15 — тень Panel остаётся частью того же узла и не «оторвана» от шара.
Игровой HUD, баннер и результат (game_board.tscn)
Три ключевых StyleBoxFlat:
StyleBoxFlat_hud— основная верхняя панель со счётом и превью: более крупная тень (shadow_size = 8) и смещение(0, 5), чтобы панель визуально перекрывала фон и слегка парила над полем.StyleBoxFlat_banner_slot— нижний слот под рекламный баннер: тень чуть мягче (6и0.38альфы), чтобы не конкурировать с HUD по контрасту.StyleBoxFlat_result— карточка итога: самая выраженная тень (shadow_size = 14,shadow_offset (0, 8), слегка синеватыйshadow_color), чтобы модальный слой читался поверх затемненияDim.
Дополнительно добавлен общий StyleBoxFlat_toolbar_btn для компактных кнопок на поле («Меню») и «В главное меню» в оверлее — один стиль упрощает сопровождение.
Главное меню и модальные панели (title_screen.tscn)
Фон титула переведён на шейдерный слой (шаг 17), из‑за чего элементы управления должны быть ещё более отделены от ярких звёзд и туманности:
- основным кнопкам («Играть», «Новая игра», «Звук», «Правила», «Выход») заданы
StyleBoxFlat_menu_btnиStyleBoxFlat_menu_btn_hoverс тенью и контрастной обводкой; Закрытьв настройках и справке используют более плоскийStyleBoxFlat_overlay_btn— меньше тени, чтобы не спорить с рамкой родительскойPanelContainer;- у модальных панелей (настройки / правила) усилены параметры тени базового
StyleBoxFlat_settings_panel.
Цвета текста кнопок переопределены через theme_override_colors, чтобы белый шрифт не «выжигался» на светлом hover.
Шейдер планеты: контактное затемнение
Отдельная большая «капля» тени под каждым шаром потребовала бы второго TextureRect или усложнила бы CellView. Вместо этого в planet_ball.gdshader после расчёта rgb из освещения добавлен множитель по функции occlude от комбинации uv.y (положение по вертикали в текстуре шара) и радиуса r. Нижняя область шара слегка темнеет (коэффициент до ~0.82), создавая ощущение контакта с поверхностью клетки и согласуясь с тенью Panel под ним.
Это не заменяет полноценный каст-тень под объектом на произвольном фоне, но для регулярной сетки ячеек визуально стабильно и дёшево по GPU.
Настройка и типичные ошибки
Слишком большая shadow_size на маленьких клетках может дать размытый прямоугольник шире зазора между ячейками — если появится грязь между рядами, уменьшите shadow_size или альфу shadow_color. Если тени не видны на Android, проверьте, что масштаб интерфейса не опускает альфу стилей до нуля через тему проекта.
При добавлении новых Panel на игровой сцене копируйте параметры тени с ближайшего родственника (HUD или banner_slot), чтобы визуальная иерархия сохранялась.
Что можно добавить позже без поломки архитектуры
- Отдельный
Themeресурс для всего приложения с общимиStyleBoxдля кнопок разных уровней (primary / secondary / danger). - Лёгкий
shaderдляDropShadowтолько подCanvasLayerрезультатов, если понадобится цветное свечение вместо чёрной тениStyleBox. - Пер-устройственный множитель
shadow_sizeчерезGDScriptпосле чтения DPI — это уже связано со шагом адаптивной вёрстки в плане.
Отладка в редакторе и типичные сценарии регресса
Если после изменения темы проекта тени «пропали», проверьте в Project Settings → GUI → Theme не переопределён ли custom темой без поддержки StyleBoxFlat. Иногда разработчик подключает готовый Theme из ассет-стора, который задаёт StyleBoxEmpty для кнопок — тогда локальные theme_override_styles на узле сохраняют приоритет, но Panel без переопределения может потерять стиль.
При экспорте под Vulkan vs GLES3 отличаться должны только шейдеры, не StyleBox; если видите расхождение между редактором и устройством, чаще виноват разный DPI и масштаб системных шрифтов Android — попробуйте stretch режим canvas_items с display/window/stretch/scale по умолчанию проекта и не смешивайте control масштаб дерева со viewport масштабом без нужды.
Для регрессионного теста пройдите короткий чеклист: главное меню (все кнопки и модалки), партия с заполнением нижних рядов доски (тени ячеек не должны сливаться в сплошную кромку), экран результата с длинным подзаголовком (карточка не должна обрезать тень клипом родителя — при проблемах включите clip_contents только у необходимых предков или добавьте MarginContainer).
Связь с шагом 17 по восприятию глубины
После усложнения фона процедурным небом контраст между Control и фоном мог бы упасть; тени шага 16 восстанавливают иерархию слоёв. При последующей замене фона на статическую иллюстрацию имеет смысл заново подобрать shadow_color в сторону чуть более синего или фиолетового оттенка, чтобы тень не выглядела «грязной» на тёплом художественном фоне — достаточно правки StyleBox без изменения GDScript.
Ссылка на проект: Third Planet
Ссылка на игру: Google Play Rustore