~2 мин чтения

UI — Control-узлы и контейнеры

Control, anchors, контейнеры, Theme и StyleBox.

В Godot UI — это Control-узлы. Это отдельная иерархия наследников CanvasItem, со своим layout-движком, anchors, событиями. В отличие от Unity uGUI / UI Toolkit — здесь одна UI-система, встроенная.

Иерархия Control

CanvasItem
├── Node2D                       (для 2D-геймплея)
└── Control                      (для UI)
    ├── Container                (HBox/VBox/Grid/...)
    ├── Button / Label / LineEdit / ...
    ├── Panel / PanelContainer
    └── ColorRect / TextureRect

Все Control-узлы имеют:

  • position + size — позиция и размер в пикселях.
  • anchors + offsets — привязки к родителю (как Unity uGUI anchors или CSS absolute).
  • size_flags_horizontal / size_flags_vertical — поведение внутри контейнера (FILL, EXPAND, SHRINK_CENTER, …).
  • theme + theme_overrides — стилизация.

Anchors — главное

Anchor — точка на родителе, к которой “приклеена” сторона текущего Control. Четыре float’а (top, left, bottom, right) в диапазоне 0..1. Сочетания дают разные поведения:

  • (0, 0, 0, 0) — все в верхнем левом углу родителя. Размер фиксированный.
  • (0.5, 0.5, 0.5, 0.5) — центр. Размер фиксированный.
  • (0, 0, 1, 1) — растягивается на весь родитель.
  • (0, 0, 1, 0) — растягивается по ширине, прижат к верху. Высота фиксированная.

В редакторе для удобства есть Anchor presets — кнопка в верхней панели Control’а: “Top Left”, “Top Right”, “Center”, “Full Rect” и т.д.

Веб

CSS position: absolute; top/left/right/bottom + flexbox. Anchors — это absolute точки привязки, offsets — это top/left/... от них.

Unity

Concept тот же, что в Unity uGUI RectTransform. В Godot — встроенный в общий Control, нет отдельного RectTransform.

Контейнеры — авто-layout

Container-узлы автоматически раскладывают детей:

  • HBoxContainer / VBoxContainer — горизонтальный / вертикальный flexbox.
  • GridContainer — N колонок.
  • MarginContainer — padding.
  • CenterContainer — центрирует содержимое.
  • AspectRatioContainer — поддерживает соотношение сторон.
  • PanelContainer — обёртка с фоном (StyleBox).
  • ScrollContainer — прокручивает содержимое.
  • TabContainer / HSplitContainer / VSplitContainer / HFlowContainer / VFlowContainer — нишевые.

Поведение детей контейнера определяется их size_flags_horizontal / size_flags_vertical:

  • FILL — заполняет доступное место.
  • EXPAND — также берёт лишнее.
  • SHRINK_CENTER / BEGIN / END — выравнивание без растягивания.
VBoxContainer
├── Label "Score"
├── HBoxContainer
│   ├── Button "Pause" (size_flags = EXPAND_FILL)
│   └── Button "Quit" (size_flags = EXPAND_FILL)
└── PanelContainer (size_flags = EXPAND_FILL)
    └── Label "Status..."
Контейнеры — это всё что вам нужно

Не позиционируйте UI вручную через position. Используйте Containers — layout считается автоматически на любом разрешении. Manual positioning оставьте для overlay-эффектов (drag preview, custom drawing).

Базовые контролы

  • Label — текст. text, horizontal_alignment, vertical_alignment, autowrap_mode.
  • RichTextLabel — текст с BBCode (цвета, ссылки, изображения, кастомные эффекты).
  • Button — кнопка. Сигнал pressed.
  • TextureButton — кнопка-картинка с normal/pressed/hover текстурами.
  • LineEdit / TextEdit — однострочный / многострочный ввод.
  • CheckBox / CheckButton / OptionButton (combo box).
  • Slider (HSlider / VSlider), SpinBox, ProgressBar.
  • TextureRect / ColorRect — статичная картинка / цветной прямоугольник.
  • NinePatchRect — растягиваемая текстура с фиксированными углами (для UI-панелей).

Сигналы UI

Главные:

  • Button.pressed — клик.
  • Button.toggled(button_pressed) — для toggle-кнопок.
  • LineEdit.text_changed(new_text) / text_submitted(text) (Enter).
  • Slider.value_changed(value).
  • Control.mouse_entered / mouse_exited.
  • Control.focus_entered / focus_exited.

Подключаются через Inspector → Node → Signals или из кода:

@onready var start_button: Button = $StartButton

func _ready() -> void:
    start_button.pressed.connect(_on_start_pressed)

func _on_start_pressed() -> void:
    get_tree().change_scene_to_file("res://levels/level_01.tscn")

Theme и StyleBox

Theme — ресурс со всеми стилями. Применяется к корневому Control’у (или ко всему проекту через Project Settings → GUI → Theme → Custom).

В Theme описываются:

  • Colors — цвета для каждого state каждого типа (Button.font_color, Button.font_color_hover).
  • Fonts — шрифты для каждого типа.
  • Constants — числа (отступы, padding).
  • IconsTexture2D для иконок.
  • StyleBoxes — фоны и рамки.

StyleBox — фон и обводка. Виды:

  • StyleBoxFlat — заливка с радиусом, обводкой, тенью. Главный для современных интерфейсов.
  • StyleBoxTexture — растягиваемая текстура (как NinePatchRect, но в Theme).
  • StyleBoxLine — линия (разделители).
  • StyleBoxEmpty — невидимый.
var box = StyleBoxFlat.new()
box.bg_color = Color("2a2a2a")
box.border_color = Color("6cb6ff")
box.border_width_left = 2
box.border_width_top = 2
box.border_width_right = 2
box.border_width_bottom = 2
box.corner_radius_top_left = 8
box.corner_radius_top_right = 8
box.corner_radius_bottom_left = 8
box.corner_radius_bottom_right = 8

var theme = Theme.new()
theme.set_stylebox("normal", "Button", box)

Можно также переопределять styles прямо на конкретном узле через theme_override_styles (в Inspector — секция “Theme Overrides”).

CanvasLayer — UI поверх 3D

Чтобы UI рисовался поверх 3D и не подчинялся камере, оборачивайте его в CanvasLayer:

GameScene (Node3D)
├── Player
├── World
└── HUD (CanvasLayer)
    └── Control
        ├── HealthBar
        └── ScoreLabel

Без CanvasLayer Control-узлы попадут в дефолтный canvas, и могут перекрываться 3D-объектами в зависимости от Z-order.

CanvasLayer.layer — числовой порядок (0 = дефолт, выше = сверху).

UI в 3D-мире — SubViewport

Для UI “в мире” (надписи над врагами, экраны в комнате) — SubViewport рендерит UI в текстуру, которую вы можете применить к MeshInstance3D:

EnemyNameTag (Node3D)
├── SubViewport
│   └── Label "Enemy: Goblin"
└── MeshInstance3D (Quad)
    └── material_override.albedo_texture = ViewportTexture(SubViewport)

Это аналог Unity Canvas в World Space, через ViewportTexture-механизм.

В следующей главе — PackedScene и Resource.