Простой шутер от третьего лица на Unreal Engine. Часть 1

image-loader.svg

Дисклеймер

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

Вступление

Всем привет, я Артем Тарасов и я в геймдеве уже более 5 лет. Занимался разработкой игр самых разных масштабов под мобилки, пк, консоли и VR/AR. Сейчас работаю в компании JoyWay над VR проектом Stride и также являюсь преподавателем курса Технический Game Designer Unreal Engine в Otus.

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

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

Создаем проект

При открытии движка, он предложит несколько видов преднастроек проектов. Мы с вами делаем игру, поэтому выбираем Games и жмем кнопку Next.

image-loader.svg

В следующем окне движок предложит выбрать шаблон, на основе которого мы будем делать игру. Выбираем ThirdPerson. Он уже содержит персонажа и базовую логику для перемещения. Снова жмем Next.

В следующем окне мы настраиваем сам шаблон. Немного пояснений. Мы выбираем Blueprint проект, потому что мы будем создавать проект используя только язык визуального программирования Blueprints. Платформу выбираем Desktop/Console, потому что игру мы будем делать на ПК. Остальные настройки ставьте либо как на скриншоте, либо по своему усмотрению. Снизу задаем директорию проекта, а также имя самого проекта. Я назвал его HabrTPS. Жмем Create Project.

image-loader.svg

Разбираемся с интерфейсом движка

Когда откроется проект, вы увидите что-то похожее на скриншот ниже.

image-loader.svg

Самое интересное — по центру. Окошко с игровым миром. Оно также называется Viewport. Вы можете редактировать положения и вращения объектов просто кликая по ним и меняя режим редактирования с помощью кнопок W (изменение положения), E (изменение ротации), R (изменение размера). Также, зажав ПКМ, вы можете вращать камерой (перемещая мышь) и перемещаться по миру привычными WASDQE кнопками.

Далее Content Browser. В нем вы видите все ассеты, файлы с блупринтами, карты и все, что относится к вашему проекту. Любые взаимодействия с файлами проекта нужно делать строго с помощью Content Browser внутри Unreal Engine, иначе возникнут проблемы.

World Outliner — список всех объектов на карте, где мы находимся. Их можно выделять как по-одному, так и сразу несколько, выделяя через зажатый Shift или Ctrl.

Place Actors — панель, в которой вы можете найти любой интересующий вас объект и перетащить его на сцену, как в гифке ниже.

image-loader.svg

Запускаем шаблон в движке

Запустим шаблон в игровом режиме, нажав кнопку Play

image-loader.svg

Мы уже можем бегать, прыгать и осматриваться

image-loader.svg

Скачиваем в проект пушки и анимации

Заходим в Unreal Marketplace и ищем Animation Starter Pack и FPS Weapon Bundle. Покупаем их (беслпатно — это все-таки покупка, да-да). В Epic games launcher жмем Add To Project и выбираем наш проект.

image-loader.svgimage-loader.svg

Если в списке проекта вдруг не будет нашего проекта, то не пугайтесь, а просто жмите на галочку Show All Projects, выбирайте последнюю версию и добавляйте набор к проекту, несмотря на предупреждение о несовместимости версий.

Теперь наборы отображаются в Content Browser и мы можем использовать их для нашего проекта.

image-loader.svg

Заменяем стандартного персонажа на боевого

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

Нам нужно выделить нашего игрового персонажа и нажать Backspace или Delete, чтобы удалить его.

image-loader.svg

После этого ищем в папке AnimStarterPack персонажа, который называется Ue4ASP_Character и перетаскиваем его в Viewport.

image-loader.svg

Теперь, чтобы мы автоматически начинали игру именно за этот персонаж, нам необходимо в панели Details установить Auto Possess Player — Player0

image-loader.svg

Затем, когда мы нажмем Play, мы начнем играть за нового персонажа.

image-loader.svg

Выдаем оружие персонажу

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

Вы увидите что-то похожее на скриншот ниже

image-loader.svg

Нас сейчас интересуют вкладки Construct script и Viewport. Во viewport мы можем увидеть как будет выглядеть то, что мы насоздавали в нашем блупринте в игровом мире. А в Construction script находится логика, которая выполняется каждый раз, когда мы меняем положение нашего персонажа в редакторе в сцене и/или когда персонаж появляется в игровом мире. В дальнейшем воспринимайте Construction script как кусок кода, который выполняется всякий раз, когда персонаж проходит инициализацию (в т.ч. и после изменения свойств). Открываем вкладку Construction script. Видим следующее.

image-loader.svg

Перемещаться по рабочей области мы можем, зажав ПКМ.

Следующее, что нам нужно сделать — это выдать оружие нашему персонажу. В Unreal Engine для таких вещей существует система компонентов. На каждый объект, который может находиться на карте, можно повесить компоненты. Каждый компонент наделяет объект теми или иными свойствами.

image-loader.svg

Мы видим, что на нашем персонаже уже есть компоненты. Теперь кратко по каждому.

  • Capsule Component (коллизия, то, что позволяет нашему персонажу соприкасаться с окружающим его миром, для столкновений в играх используется облегченная модель коллизий, такие как капсула — для упрощения расчетов и увеличения FPS, как следствие)

  • Arrow (визуальная стрелочка, которая не отображается в игре, полезна исклютельно для редактирования и удобства работы дизайнеров)

  • Mesh (тело нашего персонажа, именно этот компонент отвечает за то, что тело отображается, а также именно на нем проигрываются все анимации)

  • CameraBoom (умный компонент, который следит за положением камеры и приближает ее к персонажу, если она упирается в стену. таким образом мы не проходим сквозь стену нашей камерой)

  • PlayerCamera (камера от лица которой мы видим все происходящее в игре)

  • Character Movement (наделяет нашего персонажа возможностью передвигаться, прыгать, плавать, летать и делать очень много всего. у меня есть информация еще не для одной статьи именно про него)

Нам нужно добавить оружие. Нажимаем на Add Component и ищем Skeletal Mesh и перетаскиваем его на компонент Mesh, чтобы закрепить компонент на теле нашего персонажа.

image-loader.svg

Теперь нужно поставить модель нашего оружия внутрь этого компонента, чтобы оно отображалось. Я выберу AK 47.

image-loader.svg

Но, как мы видим, оружие находится не в руках у персонажа, а в ногах. Вот именно здесь мы и используем Construct Script. Заходим внутрь Construct Script, жмем ПКМ по пустой области и находим команду (в дальнейшем буду называть их нодами) Attach Component To Component (Skeletal mesh). После добавления оно должно выглядеть вот так.

image-loader.svg

Теперь нам нужно с помощью простого зажатия обведенного Пина (соединения) соединить эти две ноды как показано на скриншоте ниже. Таким образом после команды Construction Script (а точнее не команды, а начала функции) выполнится команда AttachComponentToComponent.

image-loader.svg

Как понятно по названию, нода прикрепляет один компонент к другому. У нас уже указан Target (т.е. то, что мы прикрепляем), но не указан Parent (к чему мы будем крепить Target). Просто перетягиваем Drag&Drop операцией компонент Mesh на граф и подсоединяем его в Parent.

image-loader.svg

Далее нам необходимо указать кость, на которую будет крепиться оружие. Указывайте hard_r в поле Socket Name.

Должно получиться вот так.

image-loader.svg

Для того, чтобы наш персонаж обновился — нужно нажать кнопку Compile внутри нашего блупринта.

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

image-loader.svg

Ура! У нас есть оружие.

Стрельба методом HitScan

В игровой индустрии распространены два основных метода стрельбы. Физическими пульками, которые действительно летят по баллистике и врезаются в объекты. И так называемая лучевая стрельба (или же HitScan). HitScan выстреливает лучем (без баллистики) и поражает цель мгновенно. Такой подход используется в огромном количестве современных соревновательных и не только игр.

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

Итак, первое, что нам нужно сделать — понять, что игрок нажал ЛКМ. Для этого идем в EventGraph, нажимаем ПКМ по пустой области и ищем ноду Left Mouse Button.

image-loader.svg

Нас интересует нажатие на кнопку, поэтому мы будем работать с выходным пином Pressed. По знакомой схеме ищем ноду LineTraceByChannel, именно она будет запускать луч. Соединяем эту ноду с пином Pressed.

image-loader.svg

Теперь нам необходимо указать точки откуда мы пускаем луч и куда мы пускаем луч. Стартовая точка, как я говорил ранее — это центр экрана. Но вот незадача. Экран у нас двухмерный, а мир у нас трехмерный. Т.е. курсор мы передвигаем по плоскости, которая находится во фруструме камеры (так называется усеченная пирамида, от ближней поскости которой мы и видим мир — она по сути и является нашим экраном)

image-loader.svg

Помочь получить проекцию двумерного экрана на трехмерный мир нам поможет нода Deproject Screen To World.

Из нод, что вы видите на скриншоте, соберите вот такую конструкцию.

image-loader.svg

Deproject Screen To World принимает PlayerController (о нем не сегодня) и позицию экрана в пикселях, чтобы нам получить центр экрана — нам необходимо взять размеры всего экрана и поделить их пополам с помощью ноды деления (ее можно найти как Vector2D/float). Теперь в пине WorldPosition будет проекция экранной плоскости на 3Д мир — эта точка пойдет, как точка начала луча. Соединим все как показано ниже.

image-loader.svg

Теперь необходимо указать точку куда мы будем пускать луч. У нас также есть пин WorldDirection (который является направляющим вектором, который указывает в мировых координатах куда направлен перпендикуляр к плоскости экрана). Если вы не знакомы с основами векторной алгебры, то очень советую ознакомиться с этой статьей.

Предположим, что хотим пускать луч на 10000 едениц вперед (кстати по умолчанию единица в координатах — это 1 сантиметр). Таким образом пользуясь вектором направления создаем вот такую конструкцию.

image-loader.svg

И единственное, что нам осталось — это добавить отрисовку нашего луча. Нажимаем на стрелочку на ноде трейса и ставим настройки как на скриншоте ниже.

image-loader.svg

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

image-loader.svg

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

Что дальше?

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

Лучшей благодарностью за статью будет активность и плюсик к статье. Всем спасибо за ваше время, увидимся еще в Нереальном Движке.

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

© Habrahabr.ru