Геймдев
#статьи

Что такое блюпринты — и как они работают в Unreal Engine

Разбираем понятие и делаем первые шаги в визуальном программировании в Unreal Engine 5.

Иллюстрация: Оля Ежак для SKillbox Media

Когда-то разработка игр предполагала обязательное знание языка программирования и понимание того, как следует писать код. Людям более творческих профессий было сложно сделать проект, не прибегая к помощи технических специалистов. Сейчас же всё больше игровых движков поддерживают системы визуального программирования. Одна из таких систем — блюпринты в Unreal Engine.

Из этого материала вы узнаете:


Общее определение

Блюпринт (англ. blueprint) — система визуального программирования в Unreal Engine 4 и Unreal Engine 5 на основе нодов с данными: событиями и функциями. Их можно связывать между собой и формировать элементы геймплея. Различают несколько видов блюпринтов, рассчитанных на определённые задачи — от создания события на уровне до интерфейсов и макросов, которые можно использовать как основу для другого блюпринта.

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

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

Предшественницей блюпринтов считается система Kismet из движка UE3 UDK.

Вид системы нодов Kismet в Unreal Engine 3
Скриншот: Unreal Engine 3 UDK / Epic Games

Могут ли блюпринты заменить программирование на С++

И да, и нет. Всё зависит от самого проекта и возможностей разработчика. Кто-то делает игры целиком на C++, другие используют только блюпринты. Иногда применяется комплексный подход: прототип собирают на блюпринтах, а непосредственно сам проект пишут на C++.

В дискуссиях программисты часто упоминают, что проекты на C++ получаются более оптимизированными и в них проще делать отладки. К тому же рефакторинг блюпринтов реализован в несколько раз хуже, что критично для масштабных проектов. Тем не менее блюпринты — важная составляющая движка, поэтому начинающим пользователям в любом случае стоит ознакомиться с их функционалом.

Интерфейс блюпринтов

В качестве примера рассмотрим стандартный блюпринт персонажа из шаблона Third Person — BP_ThirdPersonCharacter. По умолчанию его можно найти в Content Browser: All — Content — Third Person — Blueprints.

Файл с блюпринтом персонажа Third Person в Content Browser
Скриншот: Unreal Editor / Epic Games

Редактор блюпринта откроется в отдельном окне. Для удобства его можно сделать вкладкой в основном редакторе методом перетаскивания. Сперва ознакомимся с окном вьюпорта (вкладка Viewport).

Скриншот: Unreal Editor / Epic Games

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

Как и во вьюпорте, все эти элементы можно перемещать, вращать, изменять их размер и отдельные свойства на панели Details справа. Например, если выделить меш персонажа и найти пункт Skeletal Mesh Asset, текущую модель можно заменить на другую, которая есть в наличии.

via GIPHY

Замена женской версии стандартного манекена на мужскую
GIF: Unreal Editor / Epic Games

Все внесённые изменения в блюпринте необходимо скомпилировать кнопкой Compile. Подробнее эту функцию мы рассмотрим чуть позже. А пока продолжим обзор вьюпорта блюпринта. Слева, чуть ниже меню Components, находится раздел My Blueprint. В нём представлен список всех скриптов, которые есть в данном блюпринте: графы (Graphs), функции (Functions), макросы (Macros), переменные (Variables), функции с привязкой определённых событий (Event Dispatchers). Пункты из списка можно переносить сразу в рабочую область графа методом перетаскивания. Если кликнуть по одному из компонентов, редактор автоматически покажет его расположение в графе.

via GIPHY

Демонстрация быстрого перехода в граф
GIF: Unreal Editor / Epic Games

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

Вкладка Construction Script
Скриншот: Unreal Editor / Epic Games

Вкладка Event Graph — основное пространство, где происходит сборка нодов. Так как в нём придётся работать чаще всего, рассмотрим функционал основной панели инструментов.

Event Graph в редакторе блюпринтов. Красным выделена панель инструментов
Скриншот: Unreal Editor / Epic Games

Значок дискеты — сохранение текущего ассета.

Значок обзора — открытие папки с блюпринтом в Content Browser.

Compile — кнопка, которую часто придётся использовать в работе с блюпринтами, так как любое внесённое изменение требует компиляции. В зависимости от обстоятельств на иконке появляются дополнительные метки:

  • жёлтый знак вопроса — в блюпринт внесены изменения, нужна компиляция;
  • восклицательный знак — предупреждение о необходимости компиляции;
  • знак «стоп» — блюпринт невозможно скомпилировать, нужно внести правки или дополнительные данные;
  • зелёная галочка — блюпринт скомпилирован, его можно сохранить.

Diff — проверка соответствия текущей версии блюпринта с предыдущими ревизиями.

Find — поиск функций через строку.

Hide Unrelated — скрывает все ноды, которые не относятся к выделенному ноду в графе.

Class Settings — вызов панели настроек для выделенного класса.

Class Defaults — вызов панели настроек с изначальными данными класса.

Simulation — включает симуляцию блюпринтов во вьюпорте.

Значки проигрывателя работают так же, как и в стандартном вьюпорте Unreal Editor.

Примечание

Интерфейс панели инструментов может отличаться в зависимости от вида блюпринтов. Вид блюпринта всегда обозначен крупным шрифтом в правом нижнем углу графа.

После знакомства с интерфейсом можно приступить к написанию первого блюпринта.

Первые шаги

Для начала соберём простую функцию, которая отобразит приветственную надпись по аналогии с самым первым скриптом в языках программирования — Hello World. Создадим новый блюпринт с нуля в отдельной папке. Для этого достаточно кликнуть правой кнопкой мыши в Content Browser и в появившемся меню выбрать Blueprint Class. Далее нам предложат выбрать класс будущего блюпринта.

Меню выбора класса блюпринта
Скриншот: Unreal Editor / Epic Games

Выбираем самый распространённый вариант — Actor. Даём название новому блюпринту и открываем его.

По умолчанию в редакторе графов есть три основных события:

  • Event BeginPlay — событие, которое запускается на старте игры;
  • Event ActionBeginOverlap — событие, взаимодействующее с другим актором, например зона-триггер или препятствие;
  • Event Tick — событие, которое происходит в каждом кадре.
Ноды в Event Graph по умолчанию
Скриншот: Unreal Editor / Epic Games

Попробуем создать с нуля текстовое сообщение, которое будет отображаться на экране сразу после запуска демоуровня. Правой кнопкой мыши вызываем список событий и набираем Event BeginPlay. За набор текста отвечает функция Print Text или Print String, поэтому вытягиваем цепочку из Event BeginPlay и набираем в поиске нужную функцию. Если раскрыть созданный нод, можно установить в нём дополнительные параметры.

Настройки функции Print Text
Скриншот: Unreal Editor / Epic Games

Компилируем и сохраняем созданный блюпринт. Если запустить проигрыватель сцены сейчас, ничего не произойдёт, потому что нового блюпринта в сцене физически не существует. Перетаскиваем готовый блюпринт из Content Browser в сцену и запускаем демо. Надпись появилась на экране и сразу же исчезла, так как действие происходит всего один раз. Но если вернуться в редактор графов и заменить Event BeginPlay на Event Tick, строка будет появляться в каждом кадре.

Скриншот: Unreal Editor / Epic Games

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

Теперь попробуем сделать приветственную надпись на весь экран, которая будет появляться после нажатия клавиши. Создадим новый блюпринт для интерфейса: правой кнопкой мыши в Content Browser вызываем меню создания ассетов и в самом низу находим вкладку User Interface — Widget Blueprint. В диалоговом окне выбираем User Widget, так как нам не нужны дополнительные функции. Открываем виджет, в поисковой строке раздела Palette (в левом верхнем углу) набираем Canvas Panel и перетаскиваем её в область графа. С такой рамкой удобно расположить будущий текст на экране.

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

Создание виджета
Скриншот: Unreal Editor / Epic Games

После всех манипуляций компилируем и сохраняем новый виджет. Теперь на него нужно сделать ссылку в блюпринте.

В этот раз попробуем создать функцию, которая будет запускать интерфейс по нажатию кнопки — например, клавиши 1. Для начала нам нужно зайти в настройки проекта (Project Settings). В категории Engine — Input в разделе Action Mappings набираем название действия и назначаем клавишу 1.

Назначение клавиш в настройках проекта
Скриншот: Unreal Editor / Epic Games

Примечание

В интерфейсе Unreal Engine 5.1 можно заметить подпись, что данная настройка клавиш для проекта устарела и на данный момент в движке есть более усовершенствованные системы назначения ввода — Enhanced Input Actions и Input Mapping Contexts с гибкими настройками. Но в рамках этого руководства мы рассматриваем самую простую систему ввода, и нам нужно показать общий принцип создания блюпринтов, для которых не требуются продвинутые настройки вроде удержания, клавишных комбинаций и так далее.

Небольшое руководство по работе с новой системой клавиш

Так как у нас уже есть готовая система с персонажем в шаблоне, заходим в ранее осмотренный нами блюпринт персонажа, перемещаемся на свободный участок графа и создаём новую цепочку. Если начать набирать в поиске Key, высветится подгруппа Keyboard Events, где нам нужно отыскать клавишу 1. Так как событие будет вызвано нажатием клавиши, от слота Pressed выводим связь и создаём функцию с виджетом интерфейса.

Поиск и создание интерфейса. Красным выделена функция, которую нужно выбрать
Скриншот: Unreal Editor / Epic Games

В разделе Class указываем название созданного виджета. Далее создаём ещё один нод, чтобы отобразить надпись во вьюпорте.

Красным выделена функция, которую нужно добавить
Скриншот: Unreal Editor / Epic Games

Слот Return Value связываем с Target, иначе блюпринт невозможно будет скомпилировать. Чтобы будущая надпись, выведенная на экран, со временем исчезла, добавим функцию задержки Delay. В параметре Duration выставим три секунды (3.0). Также из предыдущего нода протянем ещё одну нить для функции Remove from Parent, которая позволит убрать виджет с экрана.

Итоговый вид связки
Скриншот: Unreal Editor / Epic Games

Компилируем и сохраняем наш блюпринт. Запускаем проигрыватель в редакторе и смотрим результат.

via GIPHY

Активация надписи происходит при нажатии клавиши 1. Согласно заданным свойствам виджет исчезает через три секунды
GIF: Unreal Editor / Epic Games

Упорядочивание нодов

Если взглянуть на созданную нами связку и сравнить её с шаблонными, видно, что она нуждается в упорядочивании. Во-первых, хаотичные формы связок сложно разобрать при большом объёме данных — в результате область графа приобретает вид, который в профессиональных кругах иронично называют «лапшой». Во-вторых, это негласное правило хорошего тона в программировании блюпринтов: вряд ли коллегам захочется тратить время на дополнительную расшифровку всех узлов. Рассмотрим, как можно упорядочить ноды.

В созданной связке есть два звена, которые входят в один синий слот. Поэтому можно выбрать синюю нить и кликнуть по ней два раза. Появится дополнительное «гнездо», которое можно подвинуть, удерживая Ctrl и ЛКМ, и присоединить продублированный нод. А чтобы связка была ровной, создаём дополнительный узел и выравниваем цепочку.

via GIPHY

Процесс упорядочивания нодов
GIF: Unreal Editor / Epic Games

Если нодов в графе слишком много, во избежание путаницы желательно добавлять комментарии к каждой связке. Для этого нужно выделить все ноды и кликнуть по ним ПКМ. В открывшемся окне надо выбрать последнюю опцию — Create Comment from Selection — и далее добавить описание на панели Details. При желании можно даже настроить цвет рамки и фона. На скриншоте ниже основной фон рамки сделан прозрачным (альфа-канал), а сама рамка — серая по аналогии с шаблонными.

Финальный вид упорядоченной цепочки нода
Скриншот: Unreal Editor / Epic Games

Взаимодействие с объектами

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

Для начала укажем в настройках новую клавишу для взаимодействия по аналогии с клавишей 1, назначенной ранее. В этот раз мы назначаем клавишу E и даём ей название, например Interaction.

Создаём новый Blueprint Class (Actor). В данном примере блюпринт назван BP_Interact. Открываем его и заходим в Event Graph. Удаляем все ноды с событиями по умолчанию и создаём новый, набрав Add Custom Event… Компилируем, сохраняем и возвращаемся к блюпринту персонажа.

В Event Graph набираем название действия, которое будет выполняться клавишей E, и оно высветится в списке событий.

Скриншот: Unreal Editor / Epic Games

Новое событие связываем с функцией Cast to (название блюпринта, который создавался ранее для взаимодействия). В текущем примере она называется Cast to BP_Interact.

Скриншот: Unreal Editor / Epic Games

В следующем ноде задаём функцию взаимодействия с объектом — Interact with Object — и связываем цель Target с созданным блюпринтом.

Скриншот: Unreal Editor / Epic Games

Чтобы взаимодействие с объектом состоялось, нужно добавить переменные с условиями, при которых оно произойдёт. В разделе My Blueprints — Variables создаём переменную ObjectLookingAt и в настройках справа вместо Boolean выбираем Object Type — Actor — Object Reference.

Создание переменной
Скриншот: Unreal Editor / Epic Games

Перетаскиваем новую переменную в поле Event Graph, выбирая при этом опцию Get, и соединяем со слотом Object в ноде Cast to BP_Itnteract. Можно скомпилировать блюпринт и перейти к созданию новой цепочки.

Итоговый вид первой связки
Скриншот: Unreal Editor / Epic Games

Теперь нужно обеспечить трассировку взаимодействия. Создаём Event Tick и связываем его с нодом Line Trace By Channel. К слоту Start присоединяем функцию Get Actor Location, а к ней — Get Player Character, так как у нас проект от третьего лица. От слота Return Value в Get Player Character выводим ещё одну функцию — Get Actor Forward Vector.

Скриншот: Unreal Editor / Epic Games

В My Blueprints — Variables создаём ещё одну переменную для того, чтобы определить расстояние до объекта взаимодействия, и даём ей название Distance Forward Look. В Details для неё выбираем тип Float, после чего блюпринт потребует компиляции. После этого в Details появится дополнительный пункт Distance Forward Look, в котором нужно указать расстояние от камеры до объекта. Так как камера от третьего лица расположена достаточно далеко, пропишем дистанцию в пять метров (500). Если бы текущий шаблон был от первого лица, расстояние было бы значительно меньше (например, 200).

Перетаскиваем новую переменную в Event Graph (выбираем Get), объединяем с Get Actor Forward Vector нодом Multiply, а его, в свою очередь, связываем с Get Actor Location с помощью нода Add (раздел Operations). В итоге получается следующая схема.

Скриншот: Unreal Editor / Epic Games

Теперь нужно определить, на что распространяется Line Trace By Channel. Из слота Out Hit выводим Break Hit Result, а из слота выполнения (Exec) — Branch, которая определит условия True/False. Связываем слот Condition со слотом Return Value, ещё раз добавляем в граф ранее написанную функцию ObjectLookingAt, но уже с параметром Set — и присоединяем к True, а её синий слот — к Hit Actor в ноде Break Hit Result.

Также нужно добавить значение False — для ситуаций, когда персонаж не будет смотреть на объект. Добавляем к False ещё одну переменную ObjectLookingAt, но уже без дополнительных соединений. В итоге дополнительный участок цепочки будет выглядеть как на скриншоте ниже.

Скриншот: Unreal Editor / Epic Games

Компилируем блюпринт и возвращаемся в папку, где находится блюпринт BP_Interact, но не открываем его, а создаём дочерний класс — Create Child Blueprint Class.

Скриншот: Unreal Editor / Epic Games

Открываем новую производную от блюпринта и в меню Components нажимаем кнопку Add. Здесь нам нужно выбрать цель взаимодействия. Это может быть как новый меш-примитив (по умолчанию в списке доступны Plane, Cube, Sphere), так и уже существующий Static Mesh. В данном примере мы возьмём меш синего кубика из сцены: выбираем Static Mesh и в панели Details в окне выбора меша находим синий куб (в проекте он называется SM_ChamferCube).

Переходим в окно Event Graph, удаляем все ноды по умолчанию и создаём Event Interact With Object. Присоединяем к нему нод Print String и настраиваем его на своё усмотрение по тому же принципу, что и строку, упомянутую ранее. Компилируем, сохраняем ассет, размещаем новые кубики в сцене путём перетаскивания и тестируем результат.

via GIPHY

Каждый раз, когда игрок нажимает кнопку E, происходит взаимодействие, результатом которого является отображение текста в левом верхнем углу экрана
GIF: Unreal Editor / Epic Games

Press F…

Напоследок рассмотрим, как работает взаимодействие с анимированными объектами. Для начала создадим блюпринт интерфейса: ПКМ в области Content Browser — раздел Create Advanced Asset — Blueprints — Blueprint Interface.

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

Скриншот: Unreal Editor / Epic Games

В качестве объекта для взаимодействия у нас будет анимированная модель сундука от Mauricio Tonelli, которую можно бесплатно скачать с портала Sketchfab. Загружаем модель и все её составляющие в отдельную папку и при импорте обязательно включаем галочку Import Animations. Если материалы по каким-то причинам не отображаются, их можно быстро настроить путём перемещения готовых текстур в соответствующие слоты шейдеров.

Разобравшись с нюансами импорта, создаём новый Blueprint Class (Actor), даём ему название и открываем. В разделе Components кнопкой Add добавляем Skeletal Mesh. В панели Details находим Skeletal Mesh Asset и выбираем Skeletal Mesh сундука. Далее открываем раздел Class Settings и в Details находим опцию Interfaces. В пункте Implemented Interfaces добавляем кнопкой Add блюпринт, созданный нами ранее.

Название блюпринта высвечивается при поиске
Скриншот: Unreal Editor / Epic Games

После этого в разделе My Blueprint появится новый интерфейс Interact. Компилируем и переходим в Event Graph. Создаём событие с функцией из блюпринта интерфейса, обозначенной ранее. В данном случае это Interact.

Скриншот: Unreal Editor / Epic Games

Чтобы событие проигрывало анимацию один раз, выбираем нод Do Once и далее создаём функцию Play Animation, которая покажет, какую анимацию нужно проигрывать. По умолчанию к ней уже будет присоединён Skeletal Mesh сундука.

Скриншот: Unreal Editor / Epic Games

Компилируем блюпринт и переходим в его вьюпорт. Нам нужно создать коллизию сундука. Нажав кнопку Add, выбираем Box и подгоняем рамку так, чтобы «утопить» в ней сундук c помощью настроек Transform в Details. На всякий случай не забудьте проверить пункт Collision Presets в настройках Box: там должен быть выбран параметр OverlapAllDynamic.

Скриншот: Unreal Editor / Epic Games

При желании можно добавить в блюпринт описание наподобие тех, что встречаются в туториалах. Кнопкой Add добавляем Text Render. Появившуюся надпись размещаем и настраиваем в Details на своё усмотрение.

Настройка меша во вьюпорте
Скриншот: Unreal Editor / Epic Games

Компилируем полученный результат и возвращаемся в блюпринт персонажа, чтобы прописать ему всю эту историю.

Создаём ивент для клавиши F, как мы ранее уже делали для предыдущих операций. Добавляем функцию цикла For Each Loop With Break. К слоту Array присоединяем Get Overlapping Actors, тем самым проверяя столкновение с другими акторами. При этом столкновении будет появляться возможность взаимодействия, поэтому к Array Element присоединяем функцию Does Implement Interface. В фиолетовом слоте указываем название блюпринта интерфейса, у нас это BP_InteractInterface.

Скриншот: Unreal Editor / Epic Games

От Return Value выводим нод Branch, который определяет, что будет, если взаимодействие произошло и если оно не состоялось. Связываем его с For Each Loop with Break. Протягиваем нод Interact (Message) от Array Element и связываем его со слотом True. Также из Interact выводим связь обратно в слот Break от нода For Each Loop with Break. Итоговая схема выглядит так, как на скриншоте ниже.

Скриншот: Unreal Editor / Epic Games

Компилируем блюпринт. Размещаем блюпринт сундука в сцене. Запускаем проигрыватель и смотрим результат.

via GIPHY

Разовое открытие сундука клавишей F
GIF: Unreal Editor / Epic Games

Итог

С помощью блюпринтов мы создали несколько простых операций в проекте на Unreal Engine 5: вывод текста на экран в виде строки и в форме виджета нажатием клавиши, а также простое взаимодействие со статичными и анимированными мешами. Все эти примеры можно модифицировать, изменять и получать новые вариации.

Начинающий пользователь вполне может освоить программирование на блюпринтах. Один из главных залогов успеха в изучении — понимание логики, по которой строятся цепочки нодов. Знание английского тоже не помешает: так будет проще найти нужную функцию, набрав её в поиске. Как и любое программирование, блюпринты требуют хорошей теоретической базы. Помните, что большинство функций перешло из предыдущей версии движка, поэтому изучение блюпринтов на UE4 станет хорошим подспорьем в визуальном программировании на Unreal Engine 5.

Полезные ссылки с ресурсами

  • Официальная документация Unreal Engine.
  • Плейлист с уроками по блюпринтам как для новичков, так и для продвинутых пользователей от канала Smart Poly.
  • Руководство на «Хабре», посвящённое созданию игры по сбору объектов на UE4.
  • Экспресс-курс о создании игры на UE4 и UE5 с помощью блюпринтов от канала Cyberstars. Также на этом канале можно найти много полезной информации по изучению движка.
  • 29 подробных уроков по блюпринтам на UE4 от канала Unreal Engine Rus.
Нейросети для работы и творчества!
Хотите разобраться, как их использовать? Смотрите конференцию: четыре топ-эксперта, кейсы и практика. Онлайн, бесплатно. Кликните для подробностей.
Смотреть программу
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована