Как сделать простое «главное меню» для игры в Unreal Engine 4. Часть 1

в 20:26, , рубрики: blueprints, longread, umg, Unreal Engine, Unreal Engine 4, главное меню, разработка игр

Этот туториал – моя первая «статья» по Unreal Engine 4. Сам я относительно недавно начал осваивать данный движок и разработку игр в общем и сейчас работаю над созданием более-менее простой игры. Недавно закончил базовую версию меню для своего проекта и решил описать свой опыт в этой статье.

Данная статья не требует каких-либо специальных навыков и вам нужно лишь установить сам движок. Я буду использовать последнюю на сей день стабильную версию: 4.16.2.

Что мы будем делать?

Это меню я сделал для игры над которой сейчас работаю. В результате туториала мы сделаем нечто похожее. (Сама игра не включена в туториал).

  1. Главное меню – первый экран игры (данная статья).
  2. Меню «паузы» – то же самое меню, но с дополнительной кнопкой «Продолжить».
  3. Анимации и плавные переходы при открытии/закрытии меню.

Так как статья получилась длинной из-за скриншотов, части 2 и 3 пойдут отдельными статьями (надеюсь, в течение этой недели).

0. Создаём проект

Возьмём за основу шаблон для First Person Shooter. Вы можете взять любой другой или вообще ипользовать пустой (Blank) шаблон – для данной статьи это не имеет значения.

Я буду использовать Blueprint-шаблон, т.к. в любом случае меню удобнее создавать через UMG виджеты и визуальные скрипты, а работать с UMG из C++ не очень удобно (впрочем, зависит от сложности и предпочтений – в упомянутом мной выше проекте я использую смешанный подход).

После запуска Unreal Engine вы увидите экран создания проекта:
image

Выбираем New Project -> Blueprint -> First Person.
Вводим путь для сохранения проекта и имя проекта, нажимаем Create Project.

После запуска Unreal Engine вы увидите примерно следующее:
image

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

1. Главное меню – первый экран игры

Самый простой способ сделать главное меню – создать новый пустой уровень для меню и запускать игру именно с него.

Итак, создадим новый уровень!

Слева в Content Browser открываем папку Maps
image

Здесь на пустом месте вызываем контекстное меню и выбираем пункт Level
image

Назовём новый уровень MainMenu.

Делаем двойной клик на уровне и видим, что уровень представляет из себя ничего – просто чёрный viewport.
image

В данном случае, именно ничего нам и нужно!

В Content Browser возвращаемся на уровень выше и через то же контекстное меню создаём New Folder, называем его UI.

Открываем папку UI, через контекстное меню создаём новый виджет: Widget Blueprint
image

Назовём его снова оригинально: MainMenu. Открываем виджет двойным кликом и видим следующий экран. По-дефолту он открывается в новом окне, но вы можете перетащить вкладку в основное окно или просто развернуть его на весь экран.

image

В правом верхнем углу вьюпорта есть настройки отображения (влияют только на то, как вы видите виджет в редакторе, но не в игре). Для себя я поставлю разрешение 1080p и отцентрирую вьюпорт, чтобы всю полезную площадь занимал сам виджет

image

Из панели Palette слева перетащим на основное поле элемент Text и введём туда какую-нибудь строку. Для автоматической установки размеров элемента в соответствии с текстом отметим опцию Size To Content.

И нажмём кнопку Save в панели инструментов.
UE4 любит неожиданно вылетать, а в случае вылета все несохранённые изменения вы потеряете.

image

Добавленный текст будет названием нашей игры. С помощью «ромашки» отцентрируем его по-горизонтали и на высоте 20% от верхнего края экрана. «Ромашка» позволяет выравнивать виджеты и привязывать их к нужным точкам, очень удобно при необходимости делать интерфейсы, которые будут работать на разных разрешениях экрана.

Если вы не видите «ромашку» – выберите наш текстовый элемент, кликнув на него левой кнопкой мыши.

image

Справа, в панели 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.

image

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

Внутрь Vertical Box поместите элемент Button, а внутрь Button – элемент Text. Слева, в Hierarchy, можно проверить, что всё расположено правильно. Если нет, то там же можно переместить элементы, чтобы получилась нужная вложенность.

image

Цвета в UE4 в основном задаются четырьмя переменными типа float (RGBA: red, green, blue, alpha), каждое значение может быть от 0.0 до 1.0.
Сделаем фон кнопки прозрачным, выставив значение alpha в ноль в параметре Background color. Не забудьте предварительно выделить именно кнопку, а не текстовый элемент внутри неё.

image

У текстового элемента можно поставить размер шрифта побольше, например, 35 единиц. А сам текст поменяйте на "Начать Игру".
Картинку, как это сделать, вставлять не буду, изменение размера шрифта мы уже проходили чуть ранее, при добавлении заголовка.

Добавим ещё несколько кнопок. Для этого в панели Hierarchy вызовите контекстное меню на элементе Button, выберите пункт Copy (либо нажмите Ctrl+C / ⌘+C), затем выберите Vertical Box и вставьте скопированную кнопку 3 раза.

Поменяем текст у новых кнопок: "Настройки", "Выход", "Продолжить". Последняя расположена нелогично и надо бы поместить её на самый верх. Для этого выберем кнопку и воспользуемся кнопками перемещения, которые у нас есть благодаря Vertical Box.

На данном этапе меню должно выглядеть примерно так:

image

Отображение меню в игре

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

Перейдём на основную вкладку UE4, где у нас открыт пустой уровень с чёрным вьюпортом.

image

В верхней панели инструментов нажмём кнопку Blueprints и в появившемся меню выберем Open Level Blueprint. Откроется редактор блюпринтов, в котором можно создавать обработчики различных событий и вообще писать логику игры (не конкретно в блюпринте уровня, но в таком же интерфейсе).

image

Blueprints – мощный язык программирования, несмотря на то, что здесь вы не пишете код, а составляете его из блоков (нод). «Под капотом» там всё равно работает C++, но многие вещи намного проще и удобнее делать именно через Blueprints, вместо того, чтобы писать непосредственно код «вручную». Впрочем, верно и обратное: многие другие вещи удобнее/проще делать в коде. Поэтому при создании игры моя рекомендация – использовать комбинированный подход, а не зацикливаться на чём-то одном.

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

image

По аналогии с BeginPlay создадим рядом ноду Create Widget:

image

У нод событий (эвентов, events) обычно только один исходящий коннектор-пин – exec pin (от «execute»), пин выполнения. У других нод могут быть ещё пины параметров и пины результата. Цвета пинов параметров и результатов показывают тип значения (boolean, int, string и т.д., очень много всевозможных вариантов).

Чтобы дать понять движку, что мы хотим выполнить ноду Create Widget при наступлении события BeginPlay, соединим исходящий exec-пин ноды BeginPlay со входящим exec-пином ноды Create Widget. Для этого левой кнопкой мыши нажмите на пин и не отпуская кнопку тащите до входящего пина.

В ноде Create Widget в параметре Class выберем наш виджет MainMenu

image

Из пина параметра Owning Player тянем линию в пустое место (да, так тоже можно), отпускаем и в меню ищем ноду Get Player Controller, добавляем её. Т.к. UE4 – движок многопользовательский, этот параметр определяет, какому игроку будет показан виджет. В случае одного игрока можно просто оставить Player Index равный нулю.

image

Теперь при запуске игры виджет будет создан, но мы ничего не увидим, т.к. его ещё надо отобразить. А также – передать управление от самой игры к интерфейсу.

Для этого из Return Value ноды Create Main Menu Widget тащим коннект в пустое место и в меню ищем ноду Add to Viewport. В данном случае, при создании ноды, exec-коннект должен подключиться автоматически.

image

Треугольник в нижней части новой ноды говорит о том, что есть какие-то скрытые параметры. Нажимаем его и видим опцию ZOrder – она устанавливает порядок, в котором виджеты будут наложены друг на друга, если мы добавляем сразу несколько виджетов на экран. Для меню логично будет поставить значение побольше, чтобы меню всегда было поверх остальных виджетов. Например, 9999.

Последний штрих (на данном этапе) – нужно переключить режим ввода. Нам нужна нода Set Input Mode UI Only. В качестве параметра Target нужно указать тот же самый Player Controller, что и ранее, а в качестве виджета – объект, созданный нодой Create Widget.

image

В верхней панели инструментов нажимаем кнопку Compile. Возвращаемся в основную вкладку, сохраняем всё (меню File -> Save All) и в панели инструментов нажимаем большую кнопку Play!

image

Если всё было сделано правильно, то вы должны увидеть меню на чёрном фоне. Однако, есть проблема: курсор оказывается невидим. Ок, в панели инструментов нажимаем Stop (или просто Esc на клавиатуре).

Это исправляется просто. Идём обратно во вкладку Main Menu - Level Blueprint.
Из ноды Get Player Controller вытягиваем коннектор и создаём новую ноду Set Show Mouse Cursor.

Отмечаем галочкой параметр Show Mouse Cursor (тёмно-красный цвет пина – Boolean; установка галочки равнозначна присвоению значения true, снятие галочки – false). Подключаем ноду между BeginPlay и Create Main Menu Widget и премещаем ноды так, чтоб они не запутывались.

image

Hint: Колесом мыши можно менять зум блюпринта.

Снова нажимаем Compile и возвращаемся в основную вкладку. Нажимаем Play.
На этот раз курсор должен быть виден, а кнопки должны нажиматься (хоть и без результата).

Создание обработчиков кнопок

Возвращаемся во вкладку нашего виджета MainMenu. Если вы её закрыли или потеряли – всегда можно открыть заново двойным кликом на нужном ассете в панели Content Browser.

Так как статья получается длинной, в этой части мы сделаем только кнопки "Начать игру" и "Выход". А другие кнопки, пока что, отключим.

Выбираем кнопку "Продолжить" (удобнее сделать это в панели Hierarchy, чтобы выбрать саму кнопку, а не текстовый элемент) и справа в панели Details находим опцию Is Enabled. Чтобы не копаться в куче параметров, всегда можно воспользоваться строкой поиска вверху просто введите "enabled". Снимаем галочку.
Аналогично поступаем с кнопкой "Настройки".

В редакторе внешне ничего не изменится, но если вы снова запустите игру, то кнопки будут серыми и неактивными.

Hint: элементы виджета можно переименовать, чтобы не путаться в нескольких одноимённых Button'ах. Для этого в панели Hierarchy выберите нужный элемент и кликните на нём один раз, либо в контекстном меню выберите Rename. Я переименовал кнопки в ButtonContinue, ButtonStart, ButtonOptions и ButtonExit соответственно.

Выбираем ButtonStart и прокручиваем панель Details в самый низ, до раздела Events. Там будет несколько зелёных кнопок.

image

Нажимаем кнопку 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.

image

Нажимаем Compile и Save, запускаем, нажимаем "Начать игру"… Ура, мы в игре!

Создание обработчика ButtonExit оставляю на домашнее задание – оно даже проще: нужно просто использовать ноду Quit Game с дефолтными параметрами. Чтобы из блюпринта виджета вернуться в редактор UI можно воспользоваться переключателем справа вверху.

image

На сегодня всё!

Автор: norlin

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js