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

Прежде всего, чтобы понять, как правильно создавать игровой мир в Unity3d, стоит рассказать о его составляющих.
Первое на что стоит обратить внимание – это объект игры (GameObject). Это основной элемент игрового мира, который содержит в себе компонент по умолчанию Transform, определяющий положение, размер и ориентацию объекта в сцене. Каждый объект игры может содержать любое количество компонентов (можно их назвать скриптами), которые определяют поведение данного объекта в сцене. Некоторые компоненты могут требовать наличие других компонентов для правильной работы. Например, в прошлой статье я приводил пример назначения компонента Rigid Body кубикам, которые уже имели компонент Box Collider. Взаимодействие между данными компонентами позволяло кубику вести себя в сцене как физическому объекту, который может падать и сталкиваться с другими кубиками и другими объектами сцены, имеющими компоненты Collider.

Как я уже говорил, каждый объект игры может иметь компоненты, определяющие его поведение. Поведение может быть не явное, как в приведенном выше примере, а выполнять какие-то действия разово или на протяжении какого-то времени. Например, игровой объект может создавать другие объекты при запуске сцены, играя роль «инициализатора» игрового мира; может выполнять какие-то действия периодически, например, уничтожил ли игрок всех врагов в сцене или нет, и если уничтожил, то выполнить действия по завершению уровня.
Префаб (Prefab) – подготовленный заранее объект игрового мира. Он может содержать в себе любой сложности заготовленную структуру. Создается он очень просто: 1) В сцене создается игровой объект любой сложности; 2) в окне Project создается Prefab так же как и создается любой скрипт; 3) перетаскиванием из окна сцены созданного игрового объекта на созданный в окне Project префаб в сцене этот объект становится экземпляром префаба, а та пустая заготовка ранее созданная в окне Project становится заготовленным объектом.

Здесь следует отметить, что если префабами являются игровые объекты, содержащие в себе компоненты для визуализации моделей (Mesh Filter и Mesh Renderer), то Unity3d автоматически использует технологию инстансинга для визуализации групп одинаковых объектов.
Думаю, данного введения будет достаточно для понимания данного урока, поэтому перейдем к практической части.

[Начинаем делать заготовки.

  1. Для начала нам понадобится создать пустой проект, как это было описано в предыдущем уроке.
  2. Создадим в окне Project четыре папки: Scripts, Prefabs, Scenes и Materials.
  3. Создаем в папке Scripts два скрипта с названиями Player, Enemy.
  4. В папке Prefabs создаем два пустых префаба с такими же именами (Player, Enemy).
  5. В папке Materials создадим два материала PlayerMaterial и EnemyMaterial и дадим им зеленый и оранжевый цвет соответственно.
  6. В папку Scenes сохраняем текущую сцену под названием Game.

Должно получиться примерно так, как показано на следующем скриншоте:
Начальная сцена

Мы сначала реализуем поведение игрока, потом сделаем заготовку для поведения врага.
Итак, переходим в выбранный вами редактор кода (в моем случае Visual Studio) двойным щелчком по скрипту «Player» и помещаем в него следующий код:

using UnityEngine;
 
public class Player : MonoBehaviour
{
    // скорость ходьбы и скорость поворота в секунду
    public float moveSpeed = 2;
    public float turnSpeed = 90;
 
    private CharacterController _controller;
    private Transform _thisTransform;
 
    public void Start()
    {
        // Получаем контроллер
        _controller = GetComponent<CharacterController>();
 
        // Получаем компонент трансформации объекта, к которому привязан данный компонент
        _thisTransform = transform;
    }
 
    public void FixedUpdate()
    {
        // Рассчитываем позицию
        _controller.Move(_thisTransform.forward * moveSpeed * Time.deltaTime * Input.GetAxis("Vertical") +
                        Vector3.down * 10.0f * Time.deltaTime);
 
        // Рассчитываем поворот
        Quaternion rot = Quaternion.AngleAxis(
            turnSpeed * Time.deltaTime * Input.GetAxis("Horizontal"), Vector3.up);
        _thisTransform.rotation *= rot;
    }
}

То же самое делаем со скриптом «Enemy»:

using UnityEngine;
 
public class Enemy : MonoBehaviour
{
    // скорость ходьбы и скорость поворота в секунду
    public float moveSpeed = 2;
    public float turnSpeed = 90;
 
    private CharacterController _controller;
    private Transform _thisTransform;
    private Transform _playerTransform;
 
    public void Start()
    {
        // Получаем контроллер
        _controller = GetComponent<CharacterController>();
 
        // Получаем компонент трансформации объекта, к которому привязан данный компонент
        _thisTransform = transform;
 
        // Получаем компонент трансформации игрока
        Player player = (Player)FindObjectOfType(typeof(Player));
        _playerTransform = player.transform;
    }
 
    // Все что связано с физикой выполняем в FixedUpdate
    public void FixedUpdate()
    {
        // направление на игрока
        Vector3 playerDirection = (_playerTransform.position - _thisTransform.position).normalized;
 
        // угол поворота на игрока
        float angle = Vector3.Angle(_thisTransform.forward, playerDirection);
 
        // максимальный угол поворота на текущем кадре
        float maxAngle = turnSpeed * Time.deltaTime;
 
        // Вычисляем прямой поворот на игрока
        Quaternion rot = Quaternion.LookRotation(_playerTransform.position - _thisTransform.position);
 
        // поворачиваем врага на игрока с учетом скорости поворота
        if (maxAngle < angle)
        {
            _thisTransform.rotation = Quaternion.Slerp(_thisTransform.rotation, rot, maxAngle / angle);
        }
        else
        {
            _thisTransform.rotation = rot;
        }
 
        // если дистанция до игрока больше трех метров
        if (Vector3.Distance(_playerTransform.position, _thisTransform.position) > 3.0f)
        {
            // двигаемся к игроку
            _controller.Move(_thisTransform.forward * moveSpeed * Time.deltaTime);
        }
        else // если меньше или равна трем метрам
        {
            // здесь например стреляем в игрока
        }
 
        // гравитация
        _controller.Move(Vector3.down * 10.0f * Time.deltaTime);
    }
}

Подготавливаем сцену
На данном этапе Вы уже должны понимать, как работают скрипты поведения каждого из трех объектов, назначение каждого из используемых окон среды. Если что-то осталось непонятно, то попробуйте перечитать эту статью или вернуться к предыдущей статье.

  1. Возвращаемся в среду Unity3d и создаем три игровых объекта в сцене: два кубика и план.
  2. У кубиков удаляем Box Collider и добавляем компонент Character Controller, с помощью которого будем управлять игроком и врагами.
  3. Назначаем кубикам материалы перетаскиванием.
  4. Зададим плану масштаб(Scale) (100,1,100) для того, чтобы он принял размеры, требуемые по заданию (по умолчанию он размером 10х10) и поместим его в ноль координат, если он был создан не в нуле. На нем по умолчанию установлен компонент Mesh Collider, который позволит нашим кубикам не проваливаться.
  5. Выбираем первый кубик и добавляем ему компонент Player. Перетаскиваем этот кубик на префаб с названием Player.
  6. Выбираем второй кубик и добавляем ему компонент Enemy. Перетаскиваем этот кубик на префаб с названием Enemy.
  7. Переименовываем объекты в сцене в соответствии с их назначением.
  8. Вы должны уже были заметить, что после создания из объекта префаба – его название в сцене становится синего цвета.
  9. Расставляем наши объекты в сцене, так как нужно, создав заранее еще два экземпляра префаба Enemy просто перетащив его в сцену.
  10. Переименуем врагов так как в задании)).У меня получилось примерно так:
    результат
  11. Сохраняем сцену и запускаем.

Результат можно посмотреть здесь

VN:F [1.9.3_1094]
Rating: 8.7/10 (57 votes cast)
VN:F [1.9.3_1094]
Rating: +20 (from 26 votes)
Простой искусственный интеллект, 8.7 out of 10 based on 57 ratings

3 комментария на «Простой искусственный интеллект»

  1. GoG
    GoG пишет:

    Класс! Спасиб! Всё обьяснено просто прекрасно!

    VN:F [1.9.3_1094]
    Rating: 4.6/5 (11 votes cast)
    VN:F [1.9.3_1094]
    Rating: +9 (from 11 votes)
  2. Armando

    lewisohn@dora.progandist” rel=”nofollow”>.…

    спс….

    VA:F [1.9.3_1094]
    Rating: 5.0/5 (1 vote cast)
    VA:F [1.9.3_1094]
    Rating: 0 (from 0 votes)
  3. aaron

    forums@cleanups.grubby” rel=”nofollow”>.…

    благодарствую….

    VA:F [1.9.3_1094]
    Rating: 5.0/5 (1 vote cast)
    VA:F [1.9.3_1094]
    Rating: 0 (from 0 votes)

Ваш отзыв

Вы должны войти, чтобы оставлять комментарии.



Страница 1 of 0