Простой шутер от третьего лица на Unreal Engine. Часть 1
Дисклеймер
Эта статья писалась для новичков Unreal Engine, если вы профи, то вам будет скучно. Для нормального прочтения, осмысления и понимания происходящего ниже, необходимо знать, что такое переменная и их основные типы, что такое метод, булеву логику и самые базовые принципы программирования. Спасибо. Приступим.
Вступление
Всем привет, я Артем Тарасов и я в геймдеве уже более 5 лет. Занимался разработкой игр самых разных масштабов под мобилки, пк, консоли и VR/AR. Сейчас работаю в компании JoyWay над VR проектом Stride и также являюсь преподавателем курса Технический Game Designer Unreal Engine в Otus.
Сегодня (и в следующих частях) я расскажу и покажу, как вы можете сделать свой собственный простенький, но вполне себе рабочий шутер от третьего лица.
Для написания этой статьи я использовал версию движка 4.27. В следующих версиях могут быть отличия, но они вряд-ли будут очень значительны, поэтому не закрывайте статью в случае другого вида окошка (изучите немного вопрос).
Создаем проект
При открытии движка, он предложит несколько видов преднастроек проектов. Мы с вами делаем игру, поэтому выбираем Games и жмем кнопку Next.
В следующем окне движок предложит выбрать шаблон, на основе которого мы будем делать игру. Выбираем ThirdPerson. Он уже содержит персонажа и базовую логику для перемещения. Снова жмем Next.
В следующем окне мы настраиваем сам шаблон. Немного пояснений. Мы выбираем Blueprint проект, потому что мы будем создавать проект используя только язык визуального программирования Blueprints. Платформу выбираем Desktop/Console, потому что игру мы будем делать на ПК. Остальные настройки ставьте либо как на скриншоте, либо по своему усмотрению. Снизу задаем директорию проекта, а также имя самого проекта. Я назвал его HabrTPS. Жмем Create Project.
Разбираемся с интерфейсом движка
Когда откроется проект, вы увидите что-то похожее на скриншот ниже.
Самое интересное — по центру. Окошко с игровым миром. Оно также называется Viewport. Вы можете редактировать положения и вращения объектов просто кликая по ним и меняя режим редактирования с помощью кнопок W (изменение положения), E (изменение ротации), R (изменение размера). Также, зажав ПКМ, вы можете вращать камерой (перемещая мышь) и перемещаться по миру привычными WASDQE кнопками.
Далее Content Browser. В нем вы видите все ассеты, файлы с блупринтами, карты и все, что относится к вашему проекту. Любые взаимодействия с файлами проекта нужно делать строго с помощью Content Browser внутри Unreal Engine, иначе возникнут проблемы.
World Outliner — список всех объектов на карте, где мы находимся. Их можно выделять как по-одному, так и сразу несколько, выделяя через зажатый Shift или Ctrl.
Place Actors — панель, в которой вы можете найти любой интересующий вас объект и перетащить его на сцену, как в гифке ниже.
Запускаем шаблон в движке
Запустим шаблон в игровом режиме, нажав кнопку Play
Мы уже можем бегать, прыгать и осматриваться
Скачиваем в проект пушки и анимации
Заходим в Unreal Marketplace и ищем Animation Starter Pack и FPS Weapon Bundle. Покупаем их (беслпатно — это все-таки покупка, да-да). В Epic games launcher жмем Add To Project и выбираем наш проект.
Если в списке проекта вдруг не будет нашего проекта, то не пугайтесь, а просто жмите на галочку Show All Projects, выбирайте последнюю версию и добавляйте набор к проекту, несмотря на предупреждение о несовместимости версий.
Теперь наборы отображаются в Content Browser и мы можем использовать их для нашего проекта.
Заменяем стандартного персонажа на боевого
В наборе который мы добавили уже есть персонаж с настроенными анимациями, поэтому мы воспользуемся именно им в целях упрощения процесса.
Нам нужно выделить нашего игрового персонажа и нажать Backspace или Delete, чтобы удалить его.
После этого ищем в папке AnimStarterPack персонажа, который называется Ue4ASP_Character и перетаскиваем его в Viewport.
Теперь, чтобы мы автоматически начинали игру именно за этот персонаж, нам необходимо в панели Details установить Auto Possess Player — Player0
Затем, когда мы нажмем Play, мы начнем играть за нового персонажа.
Выдаем оружие персонажу
Сейчас нам в первый раз нужно будет взаимодействовать с так называемым Блупринтом персонажа. Для того, чтобы открыть редактор — нужно найти блупринт персонажа (ранее мы перетаскивали его на игровую карту) и два раза кликнуть по нему.
Вы увидите что-то похожее на скриншот ниже
Нас сейчас интересуют вкладки Construct script и Viewport. Во viewport мы можем увидеть как будет выглядеть то, что мы насоздавали в нашем блупринте в игровом мире. А в Construction script находится логика, которая выполняется каждый раз, когда мы меняем положение нашего персонажа в редакторе в сцене и/или когда персонаж появляется в игровом мире. В дальнейшем воспринимайте Construction script как кусок кода, который выполняется всякий раз, когда персонаж проходит инициализацию (в т.ч. и после изменения свойств). Открываем вкладку Construction script. Видим следующее.
Перемещаться по рабочей области мы можем, зажав ПКМ.
Следующее, что нам нужно сделать — это выдать оружие нашему персонажу. В Unreal Engine для таких вещей существует система компонентов. На каждый объект, который может находиться на карте, можно повесить компоненты. Каждый компонент наделяет объект теми или иными свойствами.
Мы видим, что на нашем персонаже уже есть компоненты. Теперь кратко по каждому.
Capsule Component (коллизия, то, что позволяет нашему персонажу соприкасаться с окружающим его миром, для столкновений в играх используется облегченная модель коллизий, такие как капсула — для упрощения расчетов и увеличения FPS, как следствие)
Arrow (визуальная стрелочка, которая не отображается в игре, полезна исклютельно для редактирования и удобства работы дизайнеров)
Mesh (тело нашего персонажа, именно этот компонент отвечает за то, что тело отображается, а также именно на нем проигрываются все анимации)
CameraBoom (умный компонент, который следит за положением камеры и приближает ее к персонажу, если она упирается в стену. таким образом мы не проходим сквозь стену нашей камерой)
PlayerCamera (камера от лица которой мы видим все происходящее в игре)
Character Movement (наделяет нашего персонажа возможностью передвигаться, прыгать, плавать, летать и делать очень много всего. у меня есть информация еще не для одной статьи именно про него)
Нам нужно добавить оружие. Нажимаем на Add Component и ищем Skeletal Mesh и перетаскиваем его на компонент Mesh, чтобы закрепить компонент на теле нашего персонажа.
Теперь нужно поставить модель нашего оружия внутрь этого компонента, чтобы оно отображалось. Я выберу AK 47.
Но, как мы видим, оружие находится не в руках у персонажа, а в ногах. Вот именно здесь мы и используем Construct Script. Заходим внутрь Construct Script, жмем ПКМ по пустой области и находим команду (в дальнейшем буду называть их нодами) Attach Component To Component (Skeletal mesh). После добавления оно должно выглядеть вот так.
Теперь нам нужно с помощью простого зажатия обведенного Пина (соединения) соединить эти две ноды как показано на скриншоте ниже. Таким образом после команды Construction Script (а точнее не команды, а начала функции) выполнится команда AttachComponentToComponent.
Как понятно по названию, нода прикрепляет один компонент к другому. У нас уже указан Target (т.е. то, что мы прикрепляем), но не указан Parent (к чему мы будем крепить Target). Просто перетягиваем Drag&Drop операцией компонент Mesh на граф и подсоединяем его в Parent.
Далее нам необходимо указать кость, на которую будет крепиться оружие. Указывайте hard_r в поле Socket Name.
Должно получиться вот так.
Для того, чтобы наш персонаж обновился — нужно нажать кнопку Compile внутри нашего блупринта.
Теперь нам нужно зайти в Viewport блупринта, выбрать компонент оружия и настроить его локацию и ротацию, чтобы оружие смотрелось естественно. У меня получилось вот так.
Ура! У нас есть оружие.
Стрельба методом HitScan
В игровой индустрии распространены два основных метода стрельбы. Физическими пульками, которые действительно летят по баллистике и врезаются в объекты. И так называемая лучевая стрельба (или же HitScan). HitScan выстреливает лучем (без баллистики) и поражает цель мгновенно. Такой подход используется в огромном количестве современных соревновательных и не только игр.
Вопреки многим убеждениям, в играх от третьего лица стрельба HitScan происходит не из дула пушки, а из центра нашего экрана по направлению, куда мы смотрим. Сейчас мы с вами сделаем стрельбу и отрисовку луча по нажатию ЛКМ. Стрельба пока что будет не функциональной, но сейчас нам нужно подготовить механику к дополнительной «докрутке», а нанесение урона, эффекты выстрела и прочие радости жизни будем делать в следующих частях.
Итак, первое, что нам нужно сделать — понять, что игрок нажал ЛКМ. Для этого идем в EventGraph, нажимаем ПКМ по пустой области и ищем ноду Left Mouse Button.
Нас интересует нажатие на кнопку, поэтому мы будем работать с выходным пином Pressed. По знакомой схеме ищем ноду LineTraceByChannel, именно она будет запускать луч. Соединяем эту ноду с пином Pressed.
Теперь нам необходимо указать точки откуда мы пускаем луч и куда мы пускаем луч. Стартовая точка, как я говорил ранее — это центр экрана. Но вот незадача. Экран у нас двухмерный, а мир у нас трехмерный. Т.е. курсор мы передвигаем по плоскости, которая находится во фруструме камеры (так называется усеченная пирамида, от ближней поскости которой мы и видим мир — она по сути и является нашим экраном)
Помочь получить проекцию двумерного экрана на трехмерный мир нам поможет нода Deproject Screen To World.
Из нод, что вы видите на скриншоте, соберите вот такую конструкцию.
Deproject Screen To World принимает PlayerController (о нем не сегодня) и позицию экрана в пикселях, чтобы нам получить центр экрана — нам необходимо взять размеры всего экрана и поделить их пополам с помощью ноды деления (ее можно найти как Vector2D/float). Теперь в пине WorldPosition будет проекция экранной плоскости на 3Д мир — эта точка пойдет, как точка начала луча. Соединим все как показано ниже.
Теперь необходимо указать точку куда мы будем пускать луч. У нас также есть пин WorldDirection (который является направляющим вектором, который указывает в мировых координатах куда направлен перпендикуляр к плоскости экрана). Если вы не знакомы с основами векторной алгебры, то очень советую ознакомиться с этой статьей.
Предположим, что хотим пускать луч на 10000 едениц вперед (кстати по умолчанию единица в координатах — это 1 сантиметр). Таким образом пользуясь вектором направления создаем вот такую конструкцию.
И единственное, что нам осталось — это добавить отрисовку нашего луча. Нажимаем на стрелочку на ноде трейса и ставим настройки как на скриншоте ниже.
Не забываем нажать кнопку Compile и идем тестировать в игре.
Лучи отрисовываются, как мы и ожидали. Вот именно таким образом происходит стрельба в подавляющем количестве игр от третьего лица с HitScan методом стрельбы.
Что дальше?
Сегодня вы научились основам работы с Unreal Engine, настроили своего персонажа и научились стрелять лучами. Это уже очень круто, но впереди еще очень много интересного и сложного, что предстоит узнать. В следующих уроках этого цикла статей я расскажу и покажу, как добавить противников, настроить их логику, наносить им урон, добавить различные эффекты на выстрел, добавить прицел и собрать вашу игру на Windows в готовый .exe файл, чтобы отправить друзьям.
Лучшей благодарностью за статью будет активность и плюсик к статье. Всем спасибо за ваше время, увидимся еще в Нереальном Движке.
А всех, кто хочет подробнее узнать о нашем урсе, приглашаю на бесплатный вебинар, в рамках которого вы сможете познакомиться с программой курса и подробно узнать о процессе обучения.