- PVSM.RU - https://www.pvsm.ru -

Туториал по Unreal Engine. Часть 4: UI

image

Разработчики видеоигр используют графику и текст для отображения необходимой информации, например, здоровья или очков. Это называется интерфейсом пользователя (user interface, UI).

UI в Unreal Engine 4 создаётся с помощью Unreal Motion Graphics (UMG). UMG позволяет удобно выстраивать UI, перетаскивая элементы UI, такие как кнопки и текстовые метки.

В этой части туториала вы научитесь следующему:

  • Создавать HUD-дисплей, на котором отображается счётчик и таймер
  • Отображать HUD на экране
  • Обновлять счётчик и таймер, чтобы отображать значения переменных


Стоит учесть, что мы будем использовать в этой части Blueprints. Если вам нужно освежить свои знания, то перечитайте часть туториала, посвящённую Blueprints [1].

Примечание: эта статья является одной из восьми частей туториала по Unreal Engine:

Приступаем к работе

Скачайте заготовку проекта [4] и распакуйте её. Перейдите в папку проекта и откройте GeometryCatcher.uproject.

Примечание: если откроется окно, сообщающее, что проект создан в более ранней версии Unreal editor, то всё в порядке (движок часто обновляется). Можно или выбрать опцию создания копии, или опцию преобразования самого проекта.

Нажмите на Play, чтобы начать управлять белым кубом и попробуйте ловить падающие фигуры. Куб можно перемещать горизонтально с помощью мыши. Через десять секунд фигуры перестают создаваться.

Туториал по Unreal Engine. Часть 4: UI - 2

Первое, что нужно сделать — создать HUD-дисплей, отображающий две вещи:

  • Счётчик, отслеживающий количество собранных игроком фигур
  • Таймер, отображающий количество секунд, оставшихся до завершения создания фигур

Чтобы создать всё это, нам необходимы виджеты.

О виджетах

Виджет (widget) — это элемент UI, предоставляющий UI визуальные функции. Например, виджет Button предоставляет объект, который пользователь может видеть и нажимать на него.

Туториал по Unreal Engine. Часть 4: UI - 3

Сам виджет необязательно должен быть видимым. Например, виджет Grid Panel равномерно разделяет своё пространство между его содержимым. Пользователь не может увидеть Grid Panel, но видит его воздействие.

Туториал по Unreal Engine. Часть 4: UI - 4

Кроме того, виджеты могут содержать другие виджеты. Вот пример виджета, содержащего виджет Text (метка Name) и виджет Text Box:

Туториал по Unreal Engine. Часть 4: UI - 5

Можно даже создать виджет, являющийся целым интерфейсом, например, экраном меню. Ниже представлен пример виджета, созданного так, чтобы он выглядел как начальный экран игры. Все элементы UI тоже являются виджетами и содержатся внутри виджета начального экрана.

Туториал по Unreal Engine. Часть 4: UI - 6

Итак, мы узнали, что такое виджеты. Теперь можно создать виджет для HUD.

Создание виджета

Перейдите в Content Browser и найдите папку UI. Нажмите на кнопку Add New и выберите User InterfaceWidget Blueprint. Переименуйте новый ассет в WBP_HUD.

Туториал по Unreal Engine. Часть 4: UI - 7

Дважды нажмите на WBP_HUD, чтобы открыть его в UMG UI Designer.

UMG UI Designer

UMG UI Designer состоит из семи основных элементов:

Туториал по Unreal Engine. Часть 4: UI - 8
  1. Designer: в этой области представлено визуальное отображение виджета. Перемещаться по ней можно зажав правую клавишу мыши и двигая мышью. Масштабирование выполняется прокруткой колёсика мыши.
  2. Details: здесь отображаются свойства выбранного виджета
  3. Palette: список всех виджетов, которые можно использовать. Все созданные пользователем виджеты тоже появляются здесь.
  4. Hierarchy: список всех уже используемых виджетов
  5. Animations: некоторые свойства виджетов могут иметь анимацию, например, расположение и размер. В этой панели перечислены все анимации.
  6. Timeline: при выборе анимации на этой панели показываются анимированные свойства и ключевые кадры
  7. Editor Mode: здесь можно переключаться между режимами Designer и Graph. Режим Graph почти аналогичен Event Graph у Blueprint.

Создание виджета Text

Виджеты Text отлично подходят для отображения числовой информации, например, счётчика и таймера.

Перейдите в панель Palette и найдите виджет Text. Добавьте виджет, перетащив его мышью в панель Designer.

Туториал по Unreal Engine. Часть 4: UI - 9

Содержание текста нас пока не интересует, мы изменим его позже.

Переименуйте виджет в CounterText. Это можно сделать, выбрав виджет Text и перейдя в панель Details. Введите CounterText в текстовое поле в верхней части.

Туториал по Unreal Engine. Часть 4: UI - 10

Виджеты можно двигать, перетаскивая их левой клавишей мыши в панели Designer.

Туториал по Unreal Engine. Часть 4: UI - 11

Также можно изменять размер виджетов, перетаскивая левой клавишей мыши границы. Изменение размера позволяет задать границы виджета. Unreal не будет ничего рендерить за пределами границ.

Туториал по Unreal Engine. Часть 4: UI - 12

Или же можно задать положение и размер изменением значений в панели Details. Задайте следующие свойства и значения для CounterText:

  • Position X: 200
  • Position Y: 50
  • Size X: 500
  • Size Y: 100

Туториал по Unreal Engine. Часть 4: UI - 13

На данный момент текст занимает только небольшую часть поля.

Туториал по Unreal Engine. Часть 4: UI - 14

Можно увеличить размер шрифта, перейдя в панель Details и к разделу Appearance. Справа от свойства Font есть текстовое поле для задания размера шрифта.

Туториал по Unreal Engine. Часть 4: UI - 15

Введите размер 68.

Туториал по Unreal Engine. Часть 4: UI - 16

Давайте сделаем счётчик красивее, добавив к нему значок.

Создание виджета Image

Виджеты Image — это простой способ отображения графики в UI, например, значков.

Создайте виджет Image и назовите его CounterIcon. Задайте Position X значение 75, а Position Y — значение 50. Виджет разместится рядом с CounterText.

Туториал по Unreal Engine. Часть 4: UI - 17

Чтобы задать изображение, перейдите в панель Details и зайдите в раздел Appearance. Разверните свойство Brush, а затем нажмите на раскрывающемся списке рядом с Image. Выберите T_Counter.

Туториал по Unreal Engine. Часть 4: UI - 18

Изображение будет выглядеть растянутым, потому что размер виджета отличается от размера изображения.

Туториал по Unreal Engine. Часть 4: UI - 19

Вместо изменения размера виджета мы можем использовать опцию Size To Content. Эта опция автоматически изменяет размер виджета под размер его содержимого.

Находясь в панели Details, перейдите в раздел Slot (Canvas Panel Slot). Поставьте флажок рядом с Size To Content.

Туториал по Unreal Engine. Часть 4: UI - 20

Виджет сам подгонит свой размер под изображение.

Туториал по Unreal Engine. Часть 4: UI - 21

Если игра будет запускаться с разными размерами экрана, то UI должен соответствующим образом перемещать виджеты. Чтобы сохранить компоновку UI, нужно использовать привязки.

Привязки

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

В примере ниже каждое изображение привязано к одной точке (к ближайшему углу).

Туториал по Unreal Engine. Часть 4: UI - 22

Заметьте, что каждое изображение сохраняет положение относительно своей привязки. Благодаря привязкам UI будет иметь одинаковое расположение при разных размерах экрана.

Также можно использовать привязки для автоматического изменения размера виджетов. В случае привязки к двум или более точкам виджет будет менять свой размер для сохранения относительного размера.

В примере ниже индикатор привязан к верхнему левому и верхнему правому углам.

Туториал по Unreal Engine. Часть 4: UI - 23

Вертикально индикатор перемещается, но не меняет размера, потому что на оси Y есть только одна привязка (сверху). Однако горизонтально индикатор меняет размер, потому что имеет две точки привязки по оси X.

Anchor Medallion отображает расположение привязки. Он появляется при выборе виджета.

Туториал по Unreal Engine. Часть 4: UI - 24

Привязки CounterText и CounterIcon уже находятся в нужном месте, поэтому задавать их не нужно.

Теперь мы создадим ещё по одному виджету Text и Image для таймера. Однако на этот раз мы поместим их справа.

Создание таймера

Создайте виджет Text и назовите его TimerText. Задайте следующие свойства:

  • Position X: 1225
  • Position Y: 50
  • Size X: 500
  • Size Y: 100
  • Font Size: 68
  • Justification: Align Text Right (это выровняет текст по правой стороне виджета)

Туториал по Unreal Engine. Часть 4: UI - 25

Теперь мы хотим задать привязку в правом верхнем углу. Это можно сделать, перетащив мышью круг в Anchor Medallion. Переместите Anchor Medallion в правый верхний угол.

Туториал по Unreal Engine. Часть 4: UI - 26

Заметьте, как обновляется положение относительно привязки.

Туториал по Unreal Engine. Часть 4: UI - 27

Создайте виджет Image и назовите его TimerIcon. Задайте следующие свойства:

  • Position X: 1750
  • Position Y: 50
  • Size To Content: Checked
  • BrushImage: T_Timer

Туториал по Unreal Engine. Часть 4: UI - 28

Вместо задания привязки с помощью Anchor Medallion, можно воспользоваться предустановленными значениями. Перейдите в панель Details и нажмите на раскрывающийся список рядом с Anchors, чтобы открыть предустановленные значения. Выберите третью схему (с квадратом в правом верхнем углу).

Туториал по Unreal Engine. Часть 4: UI - 29

Создание схемы UI на этом завершено. Можно убедиться в том, что привязки работают, эмулируя различные размеры экрана. Перейдите в панель Designer и нажмите на раскрывающийся список Screen Size.

Туториал по Unreal Engine. Часть 4: UI - 30

Выбор опции изменит размер WBP_HUD для соответствия опции. Ниже показано, как HUD будет выглядеть на iPad Air. Заметьте, что виджеты стали ближе друг к другу.

Туториал по Unreal Engine. Часть 4: UI - 31

В следующем разделе мы узнаем, как отображать виджет WBP_HUD.

Отображение HUD

Нажмите на Compile, а затем вернитесь в основной редактор. Перейдите в папку Blueprints и дважды щёлкните на BP_GameManager, чтобы открыть его.

HUD должен становиться видимым после запуска игры. Для этого можно использовать нод Event BeginPlay.

Найдите нод Event BeginPlay и добавьте нод Create Widget в конец цепочки нодов. Этот нод создаёт экземпляр указанного виджета.

Туториал по Unreal Engine. Часть 4: UI - 32

Нажмите на раскрывающийся список рядом с Class и выберите WBP_HUD.

Туториал по Unreal Engine. Часть 4: UI - 33

Чтобы отобразить HUD, необходимо использовать нод Add to Viewport. Перетащите левой клавишей мыши контакт Return Value нода Create Widget. Отпустите левую клавишу мыши в пустом пространстве, чтобы открыть контекстное меню. Добавьте нод Add to Viewport.

Туториал по Unreal Engine. Часть 4: UI - 34

Давайте разберёмся с порядком событий:

  1. Когда Unreal спаунит BP_GameManager, выполняются функции Restart и SetUpCamera. Эти функции настраивают несколько переменных и камеру. Если вы не знаете, что такое функция, то не волнуйтесь, скоро мы их рассмотрим.
  2. Нод Create Widget создаёт экземпляр WBP_HUD
  3. Нод Add to Viewport отображает WBP_HUD

Нажмите на Compile и вернитесь в основной редактор. Нажмите на Play, чтобы запустить игру с новым HUD.

Туториал по Unreal Engine. Часть 4: UI - 35

Чтобы отобразить значения счётчика и таймера, нам нужны переменные для хранения этой информации. Эти переменные можно найти в BP_GameManager.

Туториал по Unreal Engine. Часть 4: UI - 36

Чтобы использовать эти переменные. нам нужен способ получения доступа к BP_GameManager из WBP_HUD. Для этого можно применить переменную-ссылку.

Переменные-ссылки

Хранить ссылки полезно, потому что они позволяют удобно получать доступ к экземплярам.

Представьте, что у вас есть одна коробка, в которой лежит мяч. Если нам нужно найти и изучить мяч, то это будет просто, потому что у нас есть всего одна коробка.

Туториал по Unreal Engine. Часть 4: UI - 37

А теперь представьте, что у нас сотня коробок, но мяч есть только в одной. Нам нужно будет проверять каждую коробку, пока мы не найдём коробку с мячом.

Туториал по Unreal Engine. Часть 4: UI - 38

Каждый раз, когда нам нужно будет изучить мяч, придётся выполнять эту операцию. Это быстро приведёт к проблемам с производительностью.

Благодаря ссылкам можно отслеживать коробку с мячом. Таким образом, нам не придётся проверять каждую коробку.

Туториал по Unreal Engine. Часть 4: UI - 39

Создание переменной-ссылки

Откройте WBP_HUD и переключитесь в режим Graph, перейдя в Editor Mode и выбрав Graph.

Туториал по Unreal Engine. Часть 4: UI - 40

Перейдите на вкладку My Blueprint и создайте новую переменную GameManager.

Перейдите в панель Details и нажмите на раскрывающийся список рядом с Variable Type. Найдите BP_GameManager и выберите BP Game ManagerObject Reference.

Туториал по Unreal Engine. Часть 4: UI - 41

Задание переменной-ссылки

Нажмите на Compile и откройте BP_GameManager.

Найдите нод Create Widget и перетащите левой клавишей мыши контакт Return Value. Отпустите левую клавишу на пустом пространстве и выберите из меню Set Game Manager.

Затем соедините нод Add to Viewport с нодом Set Game Manager.

Туториал по Unreal Engine. Часть 4: UI - 42

Примечание: можно перенаправлять «провода», дважды щёлкая на них для создания нода Reroute. Перетащите левой клавишей мыши нод Reroute, чтобы перенаправить «провод».

Затем создайте нод Self и соедините его с левым контактом нода Set Game Manager. Нод Self будет указан в списке как Get a reference to self.

Туториал по Unreal Engine. Часть 4: UI - 43

Теперь, когда WBP_HUD уже создан, у нас будет ссылка на BP_GameManager.

В следующем разделе мы узнаем, как обновлять виджет с помощью функций.

Функции

Функции в Blueprints — это графы, похожие на Event Graph. В отличие от Event Graph функции можно вызывать с помощью нодов. Зачем же это может понадобиться?

Туториал по Unreal Engine. Часть 4: UI - 44

Упорядоченность

Одна из причин для использования функций — упорядоченность. Благодаря функциям можно соединить несколько нодов в один.

Посмотрите на раздел Event BeginPlay в BP_GameManager. Здесь есть две функции: Restart и SetUpCamera.

Туториал по Unreal Engine. Часть 4: UI - 45

Вот как будет выглядеть этот раздел без функций:

Туториал по Unreal Engine. Часть 4: UI - 46

Как вы видите, благодаря функциям он выглядит гораздо чище.

Повторное использование

Ещё одна причина для применения функций — повторное использование. Например, если вам нужно сбросить счётчик и таймер, то это можно запросто сделать с помощью функции Restart.

Туториал по Unreal Engine. Часть 4: UI - 47

Это позволяет сэкономить время на воссоздание нодов каждый раз, когда вам нужно сбросить эти переменные.

Мы познакомились с функциями и теперь можем использовать их для обновления виджета CounterText.

Обновление виджета

При создании виджета также автоматически создаётся и переменная-ссылка на этот виджет. Однако по умолчанию виджеты Text не имеют переменных-ссылок. Это значит, что мы не сможем задавать их свойство Text. К счастью, это легко исправить.

Нажмите на Compile и откройте WBP_HUD. Переключитесь в режим Designer.

Выберите CounterText, а затем перейдите в панель Details. Убедитесь, что в самом верху есть флажок Is Variable.

Туториал по Unreal Engine. Часть 4: UI - 48

Теперь мы сможем обновлять CounterText. Следующим шагом будет создание функции для обновления текста.

Создание функции обновления

Переключитесь обратно в режим Graph и перейдите во вкладку My Blueprint. Нажмите на значок + справа от раздела Functions.

Туториал по Unreal Engine. Часть 4: UI - 49

При этом будет создана новая функция и вы перейдёте к её графу. Переименуйте функцию в UpdateCounterText.

По умолчанию граф будет содержать нод Entry. При выполнении функции она будет начинать с этого нода.

Туториал по Unreal Engine. Часть 4: UI - 50

Чтобы CounterText отображал переменную ShapesCollected, нам нужно соединить их.

Перетащите в граф переменную GameManager. Перетащите левой клавишей мыши его контакт и отпустите на пустом пространстве. В меню выберите Get Shapes Collected.

Туториал по Unreal Engine. Часть 4: UI - 51

Чтобы задать текст, нужно будет использовать нод SetText (Text). Перетащите переменную CounterText в граф. Перетащите левой клавишей мыши её контакт и отпустите на пустом пространстве. В меню добавьте нод SetText (Text).

Туториал по Unreal Engine. Часть 4: UI - 52

SetText (Text) может получать входные данные типа Text. Однако переменная ShapesCollected имеет тип Integer. К счастью, Unreal автоматически выполняет преобразование при подключении Integer ко входу Text.

Соедините переменную ShapesCollected с контактом In Text нода Set Text (Text). Unreal автоматически создаст нод ToText (int).

Туториал по Unreal Engine. Часть 4: UI - 53

Чтобы доделать функцию, соедините нод Entry с нодом Set Text (Text).

Туториал по Unreal Engine. Часть 4: UI - 54

Порядок событий:

  1. При вызове UpdateCounterText функция получает переменную ShapesCollected от BP_GameManager
  2. Нод ToText (int) преобразует значение ShapesCollected в тип Text
  3. SetText (Text) задаёт текст CounterText из значения ToText (int)

Теперь нам нужно научиться вызывать UpdateCounterText, когда игрок ловит фигуру.

Вызов функции обновления

Лучше всего вызывать UpdateCounterText сразу после того, как игра увеличивает значение ShapesCollected. Я создал функцию IncrementShapesCollected, которая выполняет инкремент счётчика. Фигуры вызывают эту функцию, когда сталкиваются с игроком.

Туториал по Unreal Engine. Часть 4: UI - 55

Нажмите на Compile и вернитесь в BP_GameManager.

Прежде чем вызвать UpdateCounterText, нам нужна ссылка на WBP_HUD. Попробуйте создать переменную-ссылку самостоятельно!

Решение внутри

  • Найдите раздел, в котором мы создавали и отображали WBP_HUD.
  • Перетащите контакт Return Value нода Create Widget.
  • Отпустите левую клавишу мыши на пустом пространстве и выберите в меню Promote to variable.
  • Добавьте новый нод в конец цепочки нодов

После создания переменной измените её имя на HUDWidget.

Туториал по Unreal Engine. Часть 4: UI - 56

Затем перетащите правый контакт нода Set HUDWidget и отпустите на пустом пространстве. Добавьте нод UpdateCounterText. Благодаря этому CounterText будет отображать значение ShapesCollected при запуске игры.

Туториал по Unreal Engine. Часть 4: UI - 57

Затем перейдите в панель My Blueprint и зайдите в раздел Functions. Дважды щёлкните на IncrementShapesCollected, чтобы открыть его граф.

Туториал по Unreal Engine. Часть 4: UI - 58

Перетащите переменную HUDWidget в граф. Перетащите его контакт и отпустите на пустом пространстве. Добавьте нод UpdateCounterText и соедините его следующим образом:

Туториал по Unreal Engine. Часть 4: UI - 59

Теперь при выполнении IncrementShapesCollected она будет увеличивать ShapesCollected, а затем вызывать UpdateCounterText. Эта функция затем обновит CounterText значением ShapesCollected.

Нажмите на Compile и закройте BP_GameManager. Нажмите на Play и соберите несколько фигур, чтобы увидеть, как обновляется виджет CounterText.

Туториал по Unreal Engine. Часть 4: UI - 60

Теперь нам нужно научиться обновлять виджет TimerText, только другим способом, который называется привязкой.

Bindings

Привязки позволяют автоматически обновлять определённые свойства виджетов. Чтобы иметь возможность привязки, свойство должно обладать раскрывающимся списком Bind.

Туториал по Unreal Engine. Часть 4: UI - 61

Можно привязывать свойства к функции или к переменной, хранящейся внутри виджета. Привязка постоянно получает значение от функции или переменной и присваивает привязанному свойству это значение.

Туториал по Unreal Engine. Часть 4: UI - 62

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

С учётом этого привязки хорошо подходят для часто изменяющихся элементов, таких как таймеры. Давайте создадим привязку для TimerText.

Создание привязки

Откройте WBP_HUD и переключитесь в режим Designer.

Выберите TimerText, а затем перейдите в раздел Content панели Details. Вы увидите, что свойство Text имеет возможность привязки. Нажмите на раскрывающийся список Bind и выберите Create Binding.

Туториал по Unreal Engine. Часть 4: UI - 63

При этом создастся новая функция и выполнится переход к её графу. Переименуйте функцию в UpdateTimerText.

Функция будет иметь нод Return с контактом Return Value типа Text. TimerText будет отображать любой текст, который вы подключите к этому контакту.

Туториал по Unreal Engine. Часть 4: UI - 64

Перетащите GameManager на граф и получите из него переменную TimeRemaining.

Соедините переменную TimeRemaining с Return Value нода Return. Как и в прошлый раз, Unreal автоматически добавит нод преобразования.

Туториал по Unreal Engine. Часть 4: UI - 65

Подведём итог:

  • Привязка будет постоянно вызывать функцию UpdateTimerText
  • Функция получает переменную TimeRemaining от BP_GameManager
  • Нод ToText (float) преобразует значение из TimeRemaining в тип Text.
  • Преобразованное значение затем выводится в нод Return

Наш HUD наконец готов. Нажмите на Compile и закройте WBP_HUD. Нажмите на Play, чтобы увидеть окончательные результаты.

Туториал по Unreal Engine. Часть 4: UI - 66

Куда двигаться дальше?

Готовый проект можно скачать здесь [5].

Теперь вы знаете основы UMG и достаточно просто можете создавать более сложные интерфейсы. Попробуйте поэкспериментировать с другими виджетами и виджетами панелей.

Если вы хотите узнать, что делают другие виджеты, то прочитайте страницу Widget Type Reference [6] в документации Unreal Engine.

Чтобы продолжить изучение, прочитайте следующий пост туториала, в котором я покажу вам, как соединить всё вместе для создания простой игры!

Автор: PatientZero

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/ui/270877

Ссылки в тексте:

[1] Blueprints: https://habrahabr.ru/post/344446/

[2] Часть 1: Знакомство с движком: https://habrahabr.ru/post/344394/

[3] Часть 3: Материалы: https://habrahabr.ru/post/344522/

[4] заготовку проекта: https://koenig-media.raywenderlich.com/uploads/2017/08/GeometryCatcherStarter.zip

[5] здесь: https://koenig-media.raywenderlich.com/uploads/2017/08/GeometryCatcherComplete.zip

[6] Widget Type Reference: https://docs.unrealengine.com/latest/INT/Engine/UMG/UserGuide/WidgetTypeReference/index.html

[7] Источник: https://habrahabr.ru/post/344600/?utm_source=habrahabr&utm_medium=rss&utm_campaign=344600