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

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

Движение

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

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

Патрулирование

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

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

Обход препятствий

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

В среде, подобной рисунку ниже, мы в основном имеем дело с открытыми пространствами и для избежания препятствия достаточно совершить 2-3 лишних движения.

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

Обход препятствий должен быть определён типом препятствий, которые могут возникнуть в игре. В этом простом примере мы будем использовать выпуклые 4-точечные полигоны, которые обычно будут в форме квадрата или ромба. Благодаря таким ограничениям типов препятствий мы можем просто найти ближайшее к месту назначения ребро, к которому и будет двигаться юнит, пока в его поле зрения не появится точка назначения.

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

Ориентирование на врага

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

И в любом случае вы хотите, чтобы враги ориентировались на юнитов игрока.

В ситуации, когда вам нужно разделить все возможные направления на 8 частей, вы можете предположить, что для того, чтобы повернуться полем зрения к другому юниту, ваш юнит должен повернуть свой фронт в его сторону на 1-4 градации направления в ту или иную сторону. Простой тест, определяющий, находится ли юнит в пределах максимального поля зрения и находится ли в одном из восьми секторов, может дать хороший результат за минимальное время.

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

Преследование

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

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

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

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

Заключение

Секрет успешной реализации всех игровых ИИ — понимание, с какими игровыми ситуациями им придется иметь дело и какие результаты вы хотите получить. Если вы можете представить все действия, что вы хотите получить, и сформулировать из них алгоритм, то вы завершите 90% работы. Однако последние 10% — заставить его работать — может легко занять в 10 раз больше времени…