UI в Unity: собираем интерфейс с текстом, кнопкой и адаптацией к размеру окна

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

Соберём небольшой интерфейс на Unity UI, который часто называют uGUI: текст счёта и кнопку его увеличения. Пример рассчитан на Unity 6 с пакетом Unity UI и TextMeshPro. Затем разберём, как перенести этот принцип на HUD игры.

ТОП-5 курсов обучения Unity:

Canvas, RectTransform и EventSystem

Canvas — поверхность, на которой Unity рисует элементы uGUI. В режиме Screen Space — Overlay она располагается поверх изображения игры. Screen Space — Camera привязывает отрисовку к камере, а World Space позволяет разместить интерфейс в игровом мире.

RectTransform описывает прямоугольник элемента, его опорные точки и размещение относительно родителя. Это не обычная мировая позиция персонажа. EventSystem обрабатывает выбор и события интерфейса вместе с подходящим input module.

Для текущего примера используем Overlay. Камеру в Canvas назначать не нужно. У Canvas должен быть Graphic Raycaster, у сцены — один рабочий EventSystem.

Создаём основу интерфейса

  1. В Hierarchy создайте UI → Canvas. Оставьте Render Mode: Screen Space — Overlay.
  2. На Canvas в компоненте Canvas Scaler выберите Scale With Screen Size. Установите Reference Resolution 1920 × 1080 и Match 0.5 как стартовую настройку.
  3. Добавьте внутрь Canvas UI → Text — TextMeshPro. Если редактор предложит импорт TMP Essential Resources, выполните его. Назовите объект ScoreText.
  4. Добавьте UI → Button — TextMeshPro. Назовите его AddButton, измените текст дочернего элемента на «Добавить балл».
  5. Создайте пустой дочерний объект UIController. На него позже прикрепим компонент управления.

Canvas Scaler масштабирует интерфейс относительно выбранной опорной величины. Параметр Match задаёт, как учитывать ширину и высоту при другом соотношении сторон. Это механизм масштабирования, а не автоматическое исправление любой неудачной композиции. Его режимы описаны в документации.

Ставим элементы с помощью anchors

Для обоих элементов выберите центральные anchors и pivot (0.5, 0.5). У ScoreText задайте Pos X 0, Pos Y 100, Width 500, Height 100, выравнивание текста по центру и размер шрифта 48. Для AddButton задайте Pos X 0, Pos Y −50, Width 420, Height 90.

Центральные anchors сохраняют положение относительно центра родителя. Для счётчика в углу вы бы выбрали anchors верхнего левого угла и задали отступ от него. Для панели, которая должна растягиваться по ширине, выбрали бы разные минимальную и максимальную точки по горизонтали.

Pivot — точка самого элемента, вокруг которой он меняет размер и поворачивается. Anchors — опорные точки в родителе. При выборе preset удержание дополнительных клавиш в Unity может менять также pivot и позицию; проверяйте числа в Inspector после применения.

Подключаем текст и кнопку к коду

Создайте файл ClickCounterUI.cs, вставьте код и прикрепите компонент к UIController. Перетащите ScoreText в поле Score Text, а AddButton — в Add Button. В списке Button → On Click дополнительные события для этого примера не нужны: подписку выполняет скрипт.

using TMPro; using UnityEngine; using UnityEngine.UI; public class ClickCounterUI : MonoBehaviour { [SerializeField] private TMP_Text scoreText; [SerializeField] private Button addButton; private int score; private void OnEnable() { if (scoreText == null || addButton == null) { Debug.LogError("Назначьте текст и кнопку в Inspector", this); enabled = false; return; } addButton.onClick.AddListener(AddPoint); Refresh(); } private void OnDisable() { if (addButton != null) addButton.onClick.RemoveListener(AddPoint); } private void AddPoint() { score++; Refresh(); } private void Refresh() { scoreText.text = quot;Счёт: {score}"; } }

OnEnable подключает обработчик, OnDisable удаляет его. Благодаря симметрии включение панели заново не добавляет лишние подписки. Счёт хранится в компоненте и сохраняется при выключении и включении этого объекта, но исчезнет при уничтожении объекта или новом запуске сцены.

Почему кнопка не нажимается

Если проект работает на новом Input System, у EventSystem нужен InputSystemUIInputModule. В Inspector обычно доступна команда замены старого модуля. У нового модуля должны быть назначены действия UI; для простого примера подойдут стандартные, которые предлагает компонент. Согласование систем ввода описано в руководстве runtime UI.

Также проверьте, что кнопка Interactable, Canvas активен и поверх кнопки нет прозрачного изображения с включённым Raycast Target. Такой элемент может перехватывать указатель, даже если визуально его почти не видно. Canvas Group способен отдельно ограничивать интерактивность и raycast.

Если счёт растёт дважды, проверьте список On Click и наличие второго компонента с подпиской. Если выводится ошибка назначения, перетащите именно компоненты из текущей сцены и включите UIController снова.

Проверяем интерфейс в разных условиях

В Play нажмите кнопку несколько раз, затем измените соотношение сторон Game: 16:9, 4:3 и вертикальный экран. Текст должен оставаться над кнопкой, а края элементов — внутри области Canvas. На узком экране может понадобиться другая композиция или более компактная подпись: масштабирование не заменяет проектирование размещения.

Для длинного текста используйте layout components и настройте перенос, размеры контейнера и ограничения. На телефоне дополнительно учитывайте безопасную область экрана. Проверяйте навигацию клавиатурой или контроллером, если это часть вашей платформы.

Когда смотреть в сторону UI Toolkit

UI Toolkit предлагает другой подход: дерево элементов, UXML и стили USS. Он используется для редакторных и runtime-интерфейсов. Выбор зависит от задачи, поддерживаемой версии и нужных возможностей. Готовые элементы uGUI нельзя просто перенести в него одним переключателем.

Начинающему достаточно сначала освоить одну систему: размещение, события и связь с состоянием игры. В настоящем HUD счёт лучше хранить в игровой системе, а интерфейсу поручить отображение. Общая организация логики обсуждается в статье о менеджерах.

Документация