Как создать игру, ничего не умея. Часть третья: искусственный интеллект

Пост опубликован в блогах iXBT.com, его автор не имеет отношения к редакции iXBT.com (подробнее »)
| Обзор | Компьютерные и мобильные игры
Предисловие

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

Предыдущие статьи вы можете найти по ссылкам

  1. Как создать игру, ничего не умея. Часть первая: модели и анимации
  2. Как создать игру, ничего не умея. Часть вторая: сцена (уровень), квесты, интерактивные объекты
  3. Unity: работа с Terrain

Сегодня мы с вами займёмся боевой системой и врагами.

Сцена

Для начала мы, уже зная как создаются сцены, создадим уровень, в котором будем воевать с нашими врагами. Создаём сцену — я назвал её Level_02, наполняем декорациями, и  добавляем модели врагов.
В качестве модели врага я снова буду использовать  рыцарей. Поставлю одного, дам ему имя Enemy_01, а после полной настройки добавлю его в папку Prefabs, и уже оттуда буду использовать полностью готовых рыцарей-врагов. Делаю это потому, что нет желания ставить несколько врагов, а после каждого по-отдельности настраивать. Лень — наш главный двигатель!

Искусственный интеллект

Приступим к настройке вражины! Создаю новый Animator Controller и даю ему название Enemy! Туда мы добавляем три состояния: покоя, ходьбы и удара. Так как анимации удара у нас не было, беру её с mixamo и добавляю в проект. Прописываем все транзисторы и даём названия Bool -> eWalk и eHit. Приставку Е я использую для понимания, что они принадлежат Enemy (можно этого и не делать, но мне так удобнее). Получаем такую картину:

А сейчас нам нужно научить наш ИИ видеть всё что его окружает, и поможет нам в этом NavMeshAgent.
Переносим в сцену префаб Player и добавляем ему компонент NavMeshAgent. Выбрав нашего Player, переходим во вкладку Navigation -> Objects, с зажатой клавишей ctrl нажимаю на все объекты деревьев и гор, перехожу во вкладку Bake и нажимаю на кнопку Bake. Теперь у нас есть поверхность, по которой может передвигаться как наш персонаж, так и ИИ. 

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

Создаём пустой объект GameObject — >  Create Empty, выставляем ему значения Transform такие же, как и у нашего Enemy_01, после переименовываем пустой объект в Enemy и добавляем в него объект Enemy_01. Должно получиться вот так:

Больше Enemy_01 мы трогать не будем и займемся настройкой объекта Enemy. Добавляем ему компонент NavMeshAgent — это позволит нашему ИИ передвигаться по нашей сцене. После очередной кучи материала из интернета, я всё же запустил правильную работу ИИ, и заставил его смотреть на меня и атаковать, когда я нахожусь на достаточном расстоянии от него.

Скрипт

using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI;

public class Enemy: MonoBehaviour
{

public float DistanceToWalk;
public float DistanceToHit;
public float curDistance;
public GameObject Player;
public Animator anim;
public bool eWalk;
public bool eHit;
public float Hit;
public float DelayBetweenAnim;
public float DelayeHit;
UnityEngine.AI.NavMeshAgent _agent;

// Start is called before the first frame update
void Start()
{
_agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
}

// Update is called once per frame
void Update()
{
float distance = Vector3.Distance(Player.transform.position,transform.position);
curDistance = distance;
if (distance > DistanceToWalk)
{
return;
}

if (distance < DistanceToWalk && distance > DistanceToHit)
{
//Преследовать
_agent.SetDestination(Player.transform.position);
anim.SetBool(«eWalk», true);
}

if (distance < DistanceToWalk && distance < DistanceToHit)
{
//Преследовать и кусать
_agent.SetDestination(Player.transform.position);
transform.LookAt(Player.transform);
if (!eHit)
{
StartCoroutine(Mlee());
}
}
}

IEnumerator Mlee()
{
eHit = true;
anim.SetBool(«eHit», true);
yield return new WaitForSeconds(DelayeHit);
anim.SetBool(«eHit», false);
yield return new WaitForSeconds(DelayBetweenAnim);
eHit = false;
}

}

Не забываем, что сайт зачем-то меняет все (") на (<), и правим огрехи уже в программе. В скрипте есть строки, которые можно настраивать в зависимости от ваших расстояний и нужд, у меня же настройки получились вот такими:

Сразу скажу, что в строке Player мы добавляем объект нашего игрока (у вас он может иметь другое имя), а в строке Anim — добавляем анимацию из объекта Enemy_01 (и снова у вас она может иметь иное название), в зависимости от имен ваших объектов. Пора проверить как оно работает!

За счет строки curDistance мы видим на каком расстоянии мы находимся от нашего Enemy, и пока мы находимся дальше 20, как и было прописано в настройках, ИИ не реагирует, но стоит приблизиться, как он сразу же начинает двигаться в нашу сторону, а когда подходит достаточно близко, начинает атаковать. Я считаю, что всё работает.

Значит пора и нашему персонажу научиться бить по врагам! Добавляем в Animator Controller анимацию удара, протягиваем транзисторы, Bool будет называться punch. Дописываем пару строк в скрипт Move и тестируем!

Строчки для скрипта Move

{
if (Input.GetButtonDown(«Jump»))
GetComponent<Animator>().SetBool(«punch», true);
else if (Input.GetButtonUp(«Jump»))
GetComponent<Animator>().SetBool(«punch», false);

}

Теперь когда я нажимаю на пробел, у меня проигрывается анимация удара, а как только отпускаю — прекращается. Немного криво, но мы и не пытаемся сделать реалистичную игру =) Что же, давайте поместим оружие в руку, а то биться воображением не всегда выходит удачно =)

Интерактивные предметы

Покопавшись в папке с префабами, я обнаружил нужный мне меч, его мы уже использовали для квеста, а сейчас он нам послужит по своему прямому назначению. Добавляю его в сцену, переименовываю в Sword и создаю пустой объект GameObject -> Create Empty, назову его Weapon. За счет того, что у меня персонаж с пальцами, я могу сразу добавить к пальцам меч, но буду использовать пустой объект, прикрепляю его к пальцам, после переношу в него Sword, и обнуляю позицию. Меч точно встаёт в руку.

Проделываем ту же процедуру с Enemy. Я сразу вкладываю меч в руку, немного корректирую положение, и смотрю на результат.

Всё отлично работает, теперь мы машем мечами как в любом фильме про рыцарей =). На этом я закончу сегодняшнюю статью, а продолжение будет еще интересней: наконец перейдём к убийству мобов, получению уровней, и интерфейсу!  

Заключение

Очередная статья и очередное движение по нашему плану, мы всё ближе к финалу, осталось совсем чуть-чуть. Если приложить немного усилий и много терпения, уже на этом этапе можно создать полноценную игру! А с вами мы встретимся уже в следующей статье, всем бобра!

П. С.

Сейчас много работы, поэтому не удаётся уделить достаточно времени написанию статей, а еще я начал стримить по вечерам =) но приложу все усилия, чтобы следующая статья вышла ранее чем через неделю.

13 комментариев

87638502@vkontakte
Ты так и будешь дрочить 1 элемент глупого движка по сусекам?
n
Да, нужно закончить проект.
114808253857932665800@google
О да, опять это гавноюнити для гавножуев. Учите анриал!
M
Ну большинство игр сейчас мобильные, а при производстве мобильных игр Unity удобнее, особенно если делаешь Донатную-Сам-Знаешь-Что :-)
114808253857932665800@google
Тут я согласен с тобой. Та да… её…
n
Вы прямо последователь UE
Последний раз редактировалось
100003089743114@facebook
Зачем такой агр??? Юнити отличный движок.Просто из за его простоты на нем выпускают много шлака, но сам движок то в этом не виноват… Скажите вы на полном серьезе считаете что к Примеру игры типа Ori and the Blind Forest, который заслужили народную любовь и отличные оценки от критиков, нужно закидать какахами только из за того что они сделаны на Юнити?!?!? Хватит тупого фанбойства… и вообще автору респект за проделанную работу.Все очень познавательно и поучительно. А хейтеры визжащие о том, что хотят читать только про Анриал советую взять и написать про него… вот только, что то подсказывает, что если у человека не хватает извилин оценить сложность чей то работы, то не на какую статью он не способен априори…
n
Спасибо за поддержку, не забывайте про Subnautica
Последний раз редактировалось
114808253857932665800@google
Нахер мне писать про него тут? Это как обезьяну на спп учить…
А
Добрый день. Наткнулся на Ваши статьи, очень обрадовался! Но нашел только 3 части((( Жаль, что нет продолжения(((
n
Сейчас очень много работы и писать статьи нет времени, ближе к середине декабря закончу статьи на эту тему.
А
Понимаю. Спасибо, что ответили. Надеюсь увидеть все статьи из цикла в полном объеме.

Добавить комментарий