Этот туториал – моя первая «статья» по Unreal Engine 4. Сам я относительно недавно начал осваивать данный движок и разработку игр в общем и сейчас работаю над созданием более-менее простой игры. Недавно закончил базовую версию меню для своего проекта и решил описать свой опыт в этой статье.
Данная статья не требует каких-либо специальных навыков и вам нужно лишь установить сам движок. Я буду использовать последнюю на сей день стабильную версию: 4.16.2.
Что мы будем делать?
Это меню я сделал для игры над которой сейчас работаю. В результате туториала мы сделаем нечто похожее. (Сама игра не включена в туториал).
- Главное меню – первый экран игры (данная статья).
- Меню «паузы» – то же самое меню, но с дополнительной кнопкой «Продолжить».
- Анимации и плавные переходы при открытии/закрытии меню.
Так как статья получилась длинной из-за скриншотов, части 2 и 3 пойдут отдельными статьями (надеюсь, в течение этой недели).
0. Создаём проект
Возьмём за основу шаблон для First Person Shooter. Вы можете взять любой другой или вообще ипользовать пустой (Blank) шаблон – для данной статьи это не имеет значения.
Я буду использовать Blueprint-шаблон, т.к. в любом случае меню удобнее создавать через UMG виджеты и визуальные скрипты, а работать с UMG из C++ не очень удобно (впрочем, зависит от сложности и предпочтений – в упомянутом мной выше проекте я использую смешанный подход).
После запуска Unreal Engine вы увидите экран создания проекта:
Выбираем New Project -> Blueprint -> First Person
.
Вводим путь для сохранения проекта и имя проекта, нажимаем Create Project
.
После запуска Unreal Engine вы увидите примерно следующее:
Вы можете сразу же нажать Play
, если интересно, что из себя представляет шаблон FPS-игры.
1. Главное меню – первый экран игры
Самый простой способ сделать главное меню – создать новый пустой уровень для меню и запускать игру именно с него.
Итак, создадим новый уровень!
Слева в Content Browser
открываем папку Maps
Здесь на пустом месте вызываем контекстное меню и выбираем пункт Level
Назовём новый уровень MainMenu
.
Делаем двойной клик на уровне и видим, что уровень представляет из себя ничего – просто чёрный viewport.
В данном случае, именно ничего нам и нужно!
В Content Browser
возвращаемся на уровень выше и через то же контекстное меню создаём New Folder
, называем его UI
.
Открываем папку UI
, через контекстное меню создаём новый виджет: Widget Blueprint
Назовём его снова оригинально: MainMenu
. Открываем виджет двойным кликом и видим следующий экран. По-дефолту он открывается в новом окне, но вы можете перетащить вкладку в основное окно или просто развернуть его на весь экран.
В правом верхнем углу вьюпорта есть настройки отображения (влияют только на то, как вы видите виджет в редакторе, но не в игре). Для себя я поставлю разрешение 1080p и отцентрирую вьюпорт, чтобы всю полезную площадь занимал сам виджет
Из панели Palette
слева перетащим на основное поле элемент Text
и введём туда какую-нибудь строку. Для автоматической установки размеров элемента в соответствии с текстом отметим опцию Size To Content
.
И нажмём кнопку Save в панели инструментов.
UE4 любит неожиданно вылетать, а в случае вылета все несохранённые изменения вы потеряете.
Добавленный текст будет названием нашей игры. С помощью «ромашки» отцентрируем его по-горизонтали и на высоте 20% от верхнего края экрана. «Ромашка» позволяет выравнивать виджеты и привязывать их к нужным точкам, очень удобно при необходимости делать интерфейсы, которые будут работать на разных разрешениях экрана.
Если вы не видите «ромашку» – выберите наш текстовый элемент, кликнув на него левой кнопкой мыши.
Справа, в панели Details
, опции Position X и Y
определяют расположение элемента относительно точки привязки (центр «Ромашки») и считаются в соответствии со значениями опции Alignment
, которая задаёт точку самого элемента в значениях от 0.0
до 1.0
.
Например, значение X 0.5 Y 0.0
задаёт точку посередине элемента по-горизонтали и на верхней границе элемента по вертикали.
К слову, управлять «ромашкой» можно через опцию Anchors
.
В этой же панели Details
установим размер шрифта побольше, например 60 единиц.
Создание самого меню
Для меню UE4 предлагает удобный элемент Vertical Box
– он позволяет автоматически выравнивать несколько дочерних элементов; в нашем случае это будут кнопки (Button
).
Vertical Box
можно найти в панели Palette
, в разделе Panel
.
Установим для него точку привязки примерно посередине экрана, можно чуть выше.
Внутрь Vertical Box
поместите элемент Button
, а внутрь Button
– элемент Text
. Слева, в Hierarchy
, можно проверить, что всё расположено правильно. Если нет, то там же можно переместить элементы, чтобы получилась нужная вложенность.
Цвета в UE4 в основном задаются четырьмя переменными типа float
(RGBA: red, green, blue, alpha), каждое значение может быть от 0.0
до 1.0
.
Сделаем фон кнопки прозрачным, выставив значение alpha
в ноль в параметре Background color. Не забудьте предварительно выделить именно кнопку, а не текстовый элемент внутри неё.
У текстового элемента можно поставить размер шрифта побольше, например, 35 единиц. А сам текст поменяйте на "Начать Игру
".
Картинку, как это сделать, вставлять не буду, изменение размера шрифта мы уже проходили чуть ранее, при добавлении заголовка.
Добавим ещё несколько кнопок. Для этого в панели Hierarchy
вызовите контекстное меню на элементе Button
, выберите пункт Copy
(либо нажмите Ctrl+C
/ ⌘+C
), затем выберите Vertical Box
и вставьте скопированную кнопку 3 раза.
Поменяем текст у новых кнопок: "Настройки
", "Выход
", "Продолжить
". Последняя расположена нелогично и надо бы поместить её на самый верх. Для этого выберем кнопку и воспользуемся кнопками перемещения, которые у нас есть благодаря Vertical Box
.
На данном этапе меню должно выглядеть примерно так:
Отображение меню в игре
Теперь сделаем, чтобы созданный виджет отображался при запуске нашего уровня MainMenu
.
Перейдём на основную вкладку UE4, где у нас открыт пустой уровень с чёрным вьюпортом.
В верхней панели инструментов нажмём кнопку Blueprints
и в появившемся меню выберем Open Level Blueprint
. Откроется редактор блюпринтов, в котором можно создавать обработчики различных событий и вообще писать логику игры (не конкретно в блюпринте уровня, но в таком же интерфейсе).
Blueprints – мощный язык программирования, несмотря на то, что здесь вы не пишете код, а составляете его из блоков (нод). «Под капотом» там всё равно работает C++, но многие вещи намного проще и удобнее делать именно через Blueprints, вместо того, чтобы писать непосредственно код «вручную». Впрочем, верно и обратное: многие другие вещи удобнее/проще делать в коде. Поэтому при создании игры моя рекомендация – использовать комбинированный подход, а не зацикливаться на чём-то одном.
Если вы не видите у себя ноды BeginPlay
, то добавьте её через контекстное меню и строку поиска. Расположение ноды на поле не имеет значения, но в случае сложных скриптов лучше стараться сразу располагать ноды так, чтобы потом самим не запутаться.
По аналогии с BeginPlay
создадим рядом ноду Create Widget
:
У нод событий (эвентов, events) обычно только один исходящий коннектор-пин – exec pin (от «execute»), пин выполнения. У других нод могут быть ещё пины параметров и пины результата. Цвета пинов параметров и результатов показывают тип значения (boolean, int, string и т.д., очень много всевозможных вариантов).
Чтобы дать понять движку, что мы хотим выполнить ноду Create Widget
при наступлении события BeginPlay
, соединим исходящий exec-пин ноды BeginPlay
со входящим exec-пином ноды Create Widget
. Для этого левой кнопкой мыши нажмите на пин и не отпуская кнопку тащите до входящего пина.
В ноде Create Widget
в параметре Class
выберем наш виджет MainMenu
Из пина параметра Owning Player
тянем линию в пустое место (да, так тоже можно), отпускаем и в меню ищем ноду Get Player Controller
, добавляем её. Т.к. UE4 – движок многопользовательский, этот параметр определяет, какому игроку будет показан виджет. В случае одного игрока можно просто оставить Player Index
равный нулю.
Теперь при запуске игры виджет будет создан, но мы ничего не увидим, т.к. его ещё надо отобразить. А также – передать управление от самой игры к интерфейсу.
Для этого из Return Value
ноды Create Main Menu Widget
тащим коннект в пустое место и в меню ищем ноду Add to Viewport
. В данном случае, при создании ноды, exec-коннект должен подключиться автоматически.
Треугольник в нижней части новой ноды говорит о том, что есть какие-то скрытые параметры. Нажимаем его и видим опцию ZOrder
– она устанавливает порядок, в котором виджеты будут наложены друг на друга, если мы добавляем сразу несколько виджетов на экран. Для меню логично будет поставить значение побольше, чтобы меню всегда было поверх остальных виджетов. Например, 9999
.
Последний штрих (на данном этапе) – нужно переключить режим ввода. Нам нужна нода Set Input Mode UI Only
. В качестве параметра Target
нужно указать тот же самый Player Controller
, что и ранее, а в качестве виджета – объект, созданный нодой Create Widget
.
В верхней панели инструментов нажимаем кнопку Compile
. Возвращаемся в основную вкладку, сохраняем всё (меню File -> Save All
) и в панели инструментов нажимаем большую кнопку Play
!
Если всё было сделано правильно, то вы должны увидеть меню на чёрном фоне. Однако, есть проблема: курсор оказывается невидим. Ок, в панели инструментов нажимаем Stop
(или просто Esc
на клавиатуре).
Это исправляется просто. Идём обратно во вкладку Main Menu - Level Blueprint
.
Из ноды Get Player Controller
вытягиваем коннектор и создаём новую ноду Set Show Mouse Cursor
.
Отмечаем галочкой параметр Show Mouse Cursor
(тёмно-красный цвет пина – Boolean
; установка галочки равнозначна присвоению значения true
, снятие галочки – false
). Подключаем ноду между BeginPlay
и Create Main Menu Widget
и премещаем ноды так, чтоб они не запутывались.
Hint: Колесом мыши можно менять зум блюпринта.
Снова нажимаем Compile
и возвращаемся в основную вкладку. Нажимаем Play
.
На этот раз курсор должен быть виден, а кнопки должны нажиматься (хоть и без результата).
Создание обработчиков кнопок
Возвращаемся во вкладку нашего виджета MainMenu
. Если вы её закрыли или потеряли – всегда можно открыть заново двойным кликом на нужном ассете в панели Content Browser
.
Так как статья получается длинной, в этой части мы сделаем только кнопки "Начать игру
" и "Выход
". А другие кнопки, пока что, отключим.
Выбираем кнопку "Продолжить
" (удобнее сделать это в панели Hierarchy
, чтобы выбрать саму кнопку, а не текстовый элемент) и справа в панели Details
находим опцию Is Enabled
. Чтобы не копаться в куче параметров, всегда можно воспользоваться строкой поиска вверху просто введите "enabled
". Снимаем галочку.
Аналогично поступаем с кнопкой "Настройки
".
В редакторе внешне ничего не изменится, но если вы снова запустите игру, то кнопки будут серыми и неактивными.
Hint: элементы виджета можно переименовать, чтобы не путаться в нескольких одноимённых Button
'ах. Для этого в панели Hierarchy выберите нужный элемент и кликните на нём один раз, либо в контекстном меню выберите Rename. Я переименовал кнопки в ButtonContinue
, ButtonStart
, ButtonOptions
и ButtonExit
соответственно.
Выбираем ButtonStart
и прокручиваем панель Details
в самый низ, до раздела Events
. Там будет несколько зелёных кнопок.
Нажимаем кнопку OnClicked
и попадаем в блюпринт нашего виджета со свежесозданой нодой эвента On Clicked (ButtonStart)
. Создаём ноду Open Level
, подключаем её к эвенту и в параметре Level Name
указываем "FirstPersonExampleMap
" (название дефолтного уровня, можно посмотреть в Content Browser
).
Казалось бы, всё… но не совсем. Если помните, раньше мы переключили режим ввода на UI Only
. Теперь надо сделать обратное – переключить на Game Only
.
Для этого из ноды эвента вытягиваем коннектор и создаём ноду Set Input Mode Game Only
. При этом нода Open Level
автоматически переподключится к новой ноде, вам останется только выровнять их. Ну и не забудем, что надо указать параметр Target
в новой ноде – подключим туда ноду Get Player Controller
.
Нажимаем Compile
и Save
, запускаем, нажимаем "Начать игру
"… Ура, мы в игре!
Создание обработчика ButtonExit
оставляю на домашнее задание – оно даже проще: нужно просто использовать ноду Quit Game
с дефолтными параметрами. Чтобы из блюпринта виджета вернуться в редактор UI можно воспользоваться переключателем справа вверху.
На сегодня всё!
Автор: norlin