Войти
ПрограммированиеСтатьиОбщее

MMO на Unreal Engine #3

Внимание! Этот документ ещё не опубликован.

Автор:

Глава №3: Мобы(ИИ), стреляющая башня и HUD

День добрый.
Давненько не виделись. Собственно для начала накидаю что уже было
Глава №1: Введение
Глава №2: Игровая карта и способы хранения/чтения

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


Сегодня мы поговорим о том, что можно вытворять с такой фигнёй как HUD и что это вообще такое.

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

Сегодня для примера мы через HUD будем выводить жизни всех мобов на экране, пока без разделения на то к кому они принадлежат. Ну то есть враждебные они или это юниты игрока. Можно например добиться того, чтобы у юнитов игрока жизнь отрисовывалась так, а у мобов противника по другому (чтобы к примеру было лучше заметнее чей это моб). Можно например отображать что переносит юнит у него над головой, с помощью HUD можно например запилить свой GUI или оконную систему не используя виджеты вообще в и игре.
UE поддерживает только True Type шрифты, HUD может позволить нам выводить свой собственный нарисованный шрифт и все надписи будут именно на нём. Но сегодня я покажу лишь жизнь мобов.

Сцена должна быть заранее подготовленной и видимо в этот раз мне придется дать не только модели чтобы не отвлекаться на остальное. То есть нам надо на чём то потренироваться, поэтому я так долго не писал. Чтобы описать HUD, нужно чтобы хоть что-то было готово.
У нас уже есть карта, мы можем использовать её для вывода на экран. Но я хотел бы немного другое сейчас.

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

Если в предыдущем урок для блоков мы не стали писать класс, то в этом, придется.
Давайте создадим класс с++ CMob от Character. Я немного о нём говорил, это тот класс который может перемещаться по миру и использовать навигацию (используя свой или наш поиск пути).
Ну и как любому порядочному Мобу ему надо иметь такую переменную как жизнь. Также, коль уж мы заикнулись про "на чьей он стороне", то добавим и это. Лучше всего такое реализовать через Interface (интерфейс), специальная директива дающая(требующая) классу какие либо методы.  Очень удобно потом делать Cast, но мы сейчас просто набросаем болванку моба, и будем использовать лишь целое число для определения стороны. Также сразу сделаем их видимыми для блупринтов.
Открываем CMob.h и давайте добавим это всё в public: (лучше в нижний)

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = References)
  int32 Health; //жизнь моба
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = References)
  int32 TeamID; //на чьей он стороне

компилим, переходим обратно в редактор.

Теперь настроем ему внешний вид. Идём в корень проекта, в папку Blueprints и создаем новый выбирая базовый класс наш CMob.  Назовите блупринт BP_Mob.
Открываем его, ползём ему в левую часть. Добавляем Static Mesh (как добавить есть втором уроке), выбираем BlockWall_plate. Важно чтобы наш static mesh был внутри Mesh
Изображение
Также он должен быть выше основания капсулы, хоть на сколько нибудь.
Чтобы сменить вид нажмите на Perspective, обратите внимание, что вы также можете использовать горячие клавиши.
Изображение
Сделайте примерно как у меня. Ещё будет лучше если вы уменьшите Scale значения на: 0.2; 0.2; 1. Получится что-то вроде палки.

Теперь надо сделать ему хотя бы базовую логику. За логику будет отвечать AIController, по умолчанию он так и называется, но мы создадим свой.
С карты уберите пока BP_Map
Изображение
Далее выберите те две плиты и поставьте их в положении больше нуля. Выбираем одну и справа в Details делаем первой координаты 0,0,0.
Изображение
А второй 400,0,0.
Поставьте 10 наших Мобов на платформы. Куда хотите, главное чтобы они были на этих плитах

Теперь настроим логику. Создаем блупринт класс AIController и даем ему имя AI_Mob. (всё в папке Blueprints)
Изображение
Теперь создаем BehaviorTree и Blackboard. Первая используется для формировании логики, вторая может хранить значения (может и не пригодится, но кто его знает)
Первую назовем BT_Mob, вторую BB_Mob.
Открываем AI_Mob и идем в Constructor, там тянем нить и пишем Use Blackboard и выбираем нашу BB_Mob, затем он этого блока тянем Run BehaviorTree и выбираем наш BT_Mob.
Изображение

Теперь осталось в основном блупринте BP_Mob, выбрать что AIController у нас AI_Mob.
Изображение


В Blueprints создайте ещё один блупринт ПКМ->blueprints->Enumerations. Это и список и одновременно перечисление пронумерованных значений. Проще говоря, мы даем имя, а он хранит как число. И мы в любой момент можем превратить число в имя и наоборот.
Он нам потребуется для создания состояний моба. У каждого моба пока три основных состояния: Stand, Move, Wait. По умолчанию он всегда будет находится в первом, то есть "стоим". Из этого состояния он может перейти в состояние перемещения, а из перемещения в ожидание. Ожидание нужно для того чтобы между перемещениями была ощутимая пауза. Ну типо устал ходить, надо передохнуть.
В список добавьте эти три значения. Сохраните и дайте ему имя Enum_MobState.
Теперь откройте BB_Mob (Blackboard) выберите добавьте новую переменную State. Выберите у неё тип Enum и щелкните на эту стрелку, откроются дополнительные настройки.
Изображение
И выберите там наш Enum Mob State


Гуд, теперь мы можем спокойно заняться настройкой логики Моба. Не забывайте компилировать блупринты и сохранять.
Открываем BT_Mob, тянем от ROOT нить и ставим Sequence, это последовательное выполнение блоков. То есть если какой то блок вернет Abort, всё начнётся заново.
От Sequence тянем и выбираем в Tasks->Wait, далее справа выбираем Wait Time = 0.5 (стабильное выжидание), Random Deviation = 1 (дапозон ожидания). Это даст некую паузу Мобу перед каким либо действием. Мы сейчас сделали что она будет от 0.5 до 1.5, то есть чисто случайное.
Снова тянем от Sequence и выбираем Selector. Он позволяет выполнять только одну задачу, одну из двух или там одну из 10. Условия выбора можно сделать через блок декорации. Мы создадим его чуть позже.

Теперь вверху там есть такие вещи, как создать New Task. Это блок который мы сможем запрограммить. Выбираем его, задачу называем как TMob_Move.
Изображение
Когда будете создавать вторую задачу (Task) удобнее всего выделить существующую задачу, нажать Ctrl+W или ПКМ->Dublicate. Переименовать её в необходимое, ну и изменить имя внутри (Node Name).
В этой задаче мы будем делать передвижение моба. По идее она должна сразу открыться. В Node Name справа лучше написать "Mob Move", чтобы было понятно что эта задача делает.
Для начала добавьте сразу новую переменную в панели слева. Дайте имя KState. Затем в правой панели выберите Blackboard Key Selector и сразу скомпилируйте.
Теперь ПКМ в центральной панели и пишем Execute, выбираем тот что с AI. Owner Controller - это класс AIController, а Controlled Pawn - это Actor, ну в нашем случае BP_Mob, но для правильной работы всё равно придется сделать Cast to BP_Mob.

Сделайте вот такую схему:
Изображение
Изображение

Когда вы закончите эту схему. Сделайте копию задачи как я писал выше.
> Когда будете создавать вторую задачу (Task) удобнее всего выделить существующую задачу, нажать Ctrl+W или ПКМ->Dublicate. Переименовать её в необходимое, ну и изменить имя внутри (Node Name).
И назовите эту задачу VerifyState. Она гораздо проще
Изображение
Но тут тоже надо создать KState (и выбрать ему тип Blackboard Key Selector)
Не забываем компилировать и сохранять.

Теперь зачем это всё. Расставьте задачи как на картинке снизу.
Изображение

Теперь нажмите на VerifyState, у него появилось видимое поле KState которым мы можем управлять. В правой панели выберите как на картинке, переменную из BB (Blackboard) State.
Нажмите на MobMove и проделайте тоже самое с KState.

Теперь у вас нехватает лишь декораторов, давайте их добавим к MobMove. ПКМ по MobMove, Add Decorator->Blackboard и выберите значения как на картинке
Изображение
Почти тоже самое сделайте и для Wait
Изображение

Ну вот и всё, сохраняем и возвращаемся в редактор.
Чуть не забыл. На карту надо добавить наш навигатор. Он находится в Volume
Изображение
После этого находясь во вьюпорте нажать P (включить/выключить), это создаст такую зеленую площадь, это и есть пространство по которому могут ходить Мобы.

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

#ИИ, #Cannon, #character, #HUD, #MMO, #Mobs, #tower, #Unreal Engine

24 июня 2017