Боты/AI в Unreal Tournament

Автор: Hruka

Введение

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

Прокладка путей

Боты UT используют систему путей для навигации - вы задаете им "контрольные точки"(waypoints) и боты бегают от одной точки к другой. Такая система навигации не требует много ресурсов процессора и позволяет дизайнеру контролировать все действия ботов.

Контрольными точками являются все дочерние классы NavigatonPoint. Соответственно, PlayerStart и Teleporter тоже являются вэйпоинтами (для краткости и понятности я в дальнейшем буду называть их именно так). Некоторые вэйпоинты, такие как InventorySpot и WarpZoneMarker, создаются автоматически в процессе определения путей (об этом чуть-чуть позже). Некоторые вэйпоинты использовались только в Unreal и полностью игнорируются Unreal Tournament'ом. В из число входят AlarmPoint, ButtonMarker, PatrolPoint, QueenDest, SpawnPoint, Transporter и TriggerMarker.

После того, как вы закончите строительство уровня, вы должны нанести на карту сеть маршрутов используя простые вэйпоинты (класс NavigationPoint). Ставьте их на всех пересечениях и поворотах, избегая близости к углам и стенам (вэйпоинты должны находится на расстоянии как минимум 50 единиц от стен). Располагайте вэйпоинты так, чтобы следующий вэйпоинт был виден из предыдущего. Вэйпоинты не должны быть расположены на расстоянии больше 700 единиц. На лестницах и подъемах вэйпоинты должны быть расположены не дальше 350 единиц друг от друга. Так как PlayerStart'ы и Teleporter'ы являются вэйпоинтами, то вы не должны ставить вэйпоинты там, где PlayerStart'ы могут их заменить. Основная ваша задача - использовать минимальное количество вэйпоинтов для покрытия всей площади уровня.

Unreal Tournament начиная с версии 402 содержит встроенный генератор вэйпоинтов, который автоматически сделает большую часть работы по прокладке путей. Он попытается покрыть весь уровень вэйпоинтами, но генератор не будет ставить специальные типы контрольных точек, такие как PlayerStart, LiftCenter и т.д. Чтобы использовать встроенный генератор путей, откройте окно Log Window (команда меню Window->Log) и напишите "PATHS BUILD" там. Прокладка путей займет примерно 5-10 минут для уровня средних размеров.

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

Последний шаг в создании сети маршрутов - это определение путей. Это можно сделать, написав "PATHS DEFINE" в окне Log Window. Вы можете посмотреть на созданные маршруты в любом окне просмотра, выбрав команду "View->Show Paths" в меню этого окна. Правильно соединенные вэйпонты будут соединены красными или синими линиями в окне просмотра. Боты будут бегать как по красным, так и по синим линиям, однако синии линии для ботов более предпочтительны - они показывают более быстрый и короткий путь. Каждый раз после того, как вы меняете геометрию уровня, изменяете оружие или сетку маршрутов, вы должны определить пути для того, чтобы изменения вступили в силу.

Существует несколько проблем, связанных с погрешностями AI, допущенных для уменьшения загрузки CPU. Обязательно проверьте, что все вэйпоинты находятся на расстоянии как миниму 50 единиц друг от друга. Если два вэйпоинта будут находится слишком близко, то бот может застрять на них. В окне Log Window будут появлятся предупреждения во время определения путей, если два вэйпоинта находятся слишком близко. Эта проблема чаще всего встречается с объектами класса InventorySpot, которые создаются рядом со всеми предметами в игре. Никогда не ставьте вэйпоинты рядом с предметами для того, чтобы избежать эту проблему.

Боты будут иметь проблемы с перемещением, если вэйпоинты находятся слишком высоко над землей. Проверьте, что вэйпоинты находятся не выше чем 1,5*collisionheight бота. Обычно, таких проблем не возникает, однако на подъемах с большим уклоном вы должны понизить вэйпоинты.

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

Зоны порталов (WarpZone) должны иметь глубину не менее 70 единиц чтобы боты правильно их использовали.

Лифты

Существует два специальных типа вэйпоинтов, используемых для того, чтобы боты понимали как следует использовать лифт. Это LiftCenter и LiftExit. Поставьте LiftCenter на лифт и измените аттрибут LiftTag на значение равное Tag'у лифта. На каждом выходе из лифта поставьте по LiftExit'у с LiftTag'о равным Tag'у лифта. Убедитесь в том, что стоя на LiftExit'е, бота не может задеть лифт.

По умолчанию для Mover'ов параметр Object->InitialState равен BumpOpenTimed. Никогда не используйте это значение для лифтов! Тогда боты будут воспринимать лифты как двери. Вместо этого используйте StandOpenTimed. Боты также могут использовать лифты с триггерами. Обычно им не надо никакой дополнительной помощи для этого. Однако, если лифт вызывается Dispatcher'ом, то вы можете помочь боту, установив аттрибут LiftTrigger LiftCenter'а равным значению Tag'а Dispatcher'а.

У LiftCenter'а есть еще два используемых параметра, которые должны быть изменены только в случае необходимости. MaxZDifAdd показывает на дополнительную разницу в высоте между ботом и LiftCenter'ом, при которой бот считает LiftCenter доступным. Этот параметр надо использовать, если LiftExit находится выше или ниже крайнего положения лифта, например, если к лифту ведут ступеньки и бот должен ждать лифт перед этими ступеньками. MaxDist2D - это максимальное расстояние между ботом и LiftCenter'ом. По умолчанию оно равно 400 единицам.

Параметры вэйпоинтов

Единственным нужным параметром вэйпоинта является bOneWayPath. Если вы поставите его в true, то данный путь будет возможен только в сторону, в которую указывает вэйпоинт (стрелочка в 2D окне). Чтобы увидеть эту стрелочку, включите параметр bDirectional.

Специальные вэйпоинты

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

PlayerStart указывает на место респауна игрока. У PlayerStart'а есть два используемых параметра. Параметр TeamNumber указывает на команду, которой принадлежит этот PlayerStart. Игрока другой команды не могут на нем респауниться. Параметр bEnabled, который по умолчанию установлен в true, используется для включения/выключения PlayerStart'а. Если поставить bEnabled в false, то PlayerStart можно будет включить триггером.

AmbushPoint используется для указания точек, в которых можно хорошо покемперить. Эти вэйпоинты направленные и должны показывать в сторону, в которую должен смотреть бот, стоя на AmbushPoint'е. У данного типа вэйпоинтов есть два параметра, SightRadius, дальность видимости бота, и bSniping, который при значении true указывает, что в этом месте неплохо бы поснайперить.

DefencePoint - это подкласс AmbushPoint. Они используются в командных режимах игры. DefencePoint'ы имеют три дополнительных параметра, Team, Priority и FortTag. Параметр Team указывает на команду, игроки которой должны использовать этот DefencePoint (1-Красные 2-Синие 3-Зеленые 4-Золотые). Параметр Priority - это приоритет данного DefencePoint'а. Чем выше приоритет, тем DefencePoint важнее для ботов. FortTag - это параметр, использующийся в Assault картах чтобы связать данный DefencePoint с каким-нибудь FortStandart'ом (о различных типах игры чуть ниже).

BlockedPath - используется для того, чтобы боты не использовали путь, который в начале игры закрыт. Для того чтобы открыть путь, надо поставить триггер, ассоциированый с BlockedPath и когда триггер сработает, путь становится открытым для ботов. BlockedPath чаще всего используется в Assault картах, где некоторые двери в начале игры закрыты и открываются лишь после совершения определенного действия. Хорошим примером использования BlockedPath является карта AS-Mazon.

TranslocDest - это специальный тип LiftCenter'ов, не ассоциированный с Mover'ом. TranslocDest'ы устанавливаются в местах, в которые боты должны попадать с помощью транслокатора. Класс LiftExit должен быть помещен в точке, откуда бот должен бросать диск транслокатора и TranslocDest - это место, куда должен попасть этот диск. Другой LiftExit должен быть помещен рядом с TranslocDest'ом, как "выход" из этого "лифта". Не забудьте установить одинаковые LiftTag'и у этих объектов.
Боты будут предпологать, что каждый LiftExit доступен из TranslocDest'а. Если это не так, т.е. бот должен использовать транслокатор, чтобы добраться из TranslocDest'а в LiftExit, то замените этот LiftExit на TranslocStart.

JumpSpot - это очень походий на TranslocDest объект, он тоже используется вместе с двумя LiftExit'ами. Это точка, куба бот должен прыгать, если у него есть ботинки, если игра идет с мутатором JumpMatch или если он находится в зоне с пониженной гравитацией. Если поставить аттрибут bImpactJump в true, то боты высоких skill'ов будут использовать Impact Hammer для того, чтобы запрыгнуть. Если параметр bAlwaysAccel равен true, то бот будет "рулить" в воздухе. Используйте этот параметр только если боты не могут запрыгнуть без него.

Teleporter - это простой телепортер, перемещающий каждого игрока в другой телепортер, который устанавливается параметром URL. Если параметр URL пуст, то этот телепортер не будет никого телепортировать, а только будет служить как место назначения других телепортеров. Если поле URL содержит строку в форме "Название_уровня/название_телепортера", то телепортер будет вести на другой уровень (только в Singe Player игре). Если поле URL содержит строку вида "unreal://server.domain.com/название_уровня/название_телепортера", то телепортер будет вести на другой сервер.

Если аттрибут bEnabled телепортера установлен в False, то он не будет телепортировать игроков, вошедших в него, он будет работать только как место назначения. Аттрибут bEnabled может быть изменен триггером. Если аттрибут bChangeYaw равен true, то игрок повернется на значение Yaw телепортера, если атрибут bChangeVelocity равен true, то Velocity телепортировавшегося будет равно TargetVelcoity телепортера.

Оптимизация путей

После создания и определения путей, дизайнер уровня должен оптимизировать их и избавиться от всех ошибок. Запустите игру в режиме Spectator'а и добавьте одного, а затем еще нескольких ботов. Смотрите на игру ботов и обращайте внимание на все ошибки. Если бот застрял где-нибудь, напишите в консоли verbose, чтобы увидеть о чем думает бот. Также в исправлении ошибок может помочь просмотр Log'а (x:\utdir\system\unrealtournament.log).

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

Если игрок при респауне не может поместиться в помещение, в котором находится PlayerStart, то либо игра вылетит с ошибкой, либо вы перейдете в режим Spectator'а. В Log'е будет информация о том, какой PlayerStart вызвал ошибку.

Режимы игры UT

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

Domination

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

У ControlPoint'ов есть несколько дополнительных параметров. Когда игрок захватывает ControlPoint, для его команды может происходить какое-нибудь событие, которое задается параметрами RedEvent, BLueEvent, GoldEvent и GreenEvent. Параметр bSelfDisplayed указывает на видимость самого ControlPoint'а в игре. Параметр PointName - это название контрольной точки. Параметр ControlSound - это звук, проигрывающийся при изменении цвета контрольной точки.

Capture The Flag

В режиме игры Capture The Flag вы должны поставить объекты FlagBase (подкласс NavigationPoint), которые собственно и являются флагами. В игре может быть только две команды и каждая команда может иметь только один флаг (FlagBase). Параметр Team FlagBase'а указывает на команду, к которой принадлежит этот флаг (0 - красный, 1 - синий).

AlternatePath используется для определения альтернативных путей, которые боты могут использовать чтобы добраться до базы врага. Аттрибут Team AlternatePath'а должен указывать на команду, которая должна использовать данный путь. Аттрибут SelectionWeight используется для установки важности данного маршрута для ботов. Боты используют AlternatePath'и так: сначала они идут по кратчайшему маршруту к выбранному ими AlternatePath'у, затем от AlternatePath'а по кратчайшему маршруту идут на базу врага, к его FlagBase. Вы должны размещать AlternatePath в правильном месте, чтобы боты правильно его использовали. AlternatePath'и с аттрибутом bReturnOnly используются ботами только при возвращении с вражеской базы.

Assault

FortStandard используется для определения заданий в Assault карте. На карте может быть несколько FortStandard'ов. Аттрибут bFinalFort показывает, что при уничтожении данного FortStandard'а, уровень считается завершенным, даже если на нем все еще остаются другие FortStandard'ы. Аттрибут DefencePriority указывает на порядок, в котором боты должны защищать FortStandard'ы, чем выше приоритет, тем FortStandard главнее для ботов. Параметр NearestPathNodeTag должен всегда использоваться для того, чтобы боты знали, как добраться до FortStandard'а. Установите его равным Tag'у ближайшего доступного вэйпоинта. Необязательный параметр FallBackFort указывает на FortStandard, который боты должы будут защищать после уничтожения данного FortStandard'а (этот параметр должен быть равен Tag'у нужного FortStandard'а). Аттрибут bTriggerOnly указывает на то, что FortStandard должен быть активирован триггером, а не выстрелом.

Аттрибут bSelfDisplayed указывает на видимость FortStandard'а. Этот параметр обычно выключен и FortStandard'ы отображаются геометрие уровня. Аттрибут bFlashing показывает, что FortStandard должен мигать при попадании. Параметр bSayDestroyed указывает на то, что боты должны сообщить об уничтожении FortStandard'а (выключите этот параметр если FortStandard - это не видимое задание, а просто стратегически важное место). Если пааметр DestroyedMessage не пуст, то его значение будет отображено на экране каждого игрока при уничтожении FortStandard'а. Массивы DamageEvent[] и DamageEventThreshold[] используются для определения событий, посылающихся при нанесении определенных повреждений.

Аттрибуты ChargeDist и bForceRadius - это дополнительные параметры AI используемые для определения того, как аггресивноботы будут защищать FortStandard, когда они чувствуют, что находятся без необходимой поддержки.

Один из FortStandard'ов на уровне должен иметь установленный DefenseTime аттрибут (время, в течении которого база должна защищаться). Также, один из FortStandard'ов должен иметь аттрибут EndCamTag (Tag камеры spectatorcam, в которую вид переключается после окончания игры).

TeamCannon может быть помещен в Assault уровнях для поддержки защиты. MinigunCannon - это Minigun версия TeamCannon.

В каждом Assault уровне должен находиться объект AssaultInfo. AssaultInfo содержит текст (в массиве ObjDesc[]) и скриншоты (в массиве ObjShots[]), которые объясняют каждое задание. Аттрибут NumOfShots должен быть установлен для определения суммарного количества заданий.

Консольные команды используемые для оптимизации путей

  • PlayersOnly - все кроме игрока замирает на месте
  • AddBots n - Добавить n ботов на уровень
  • ViewClass XXX - Смотреть на игру из объекта класса XXX. Например, ViewClass bot будет показывать игру из глаз бота, если он есть на уровне. Если вы играете spectator'ом, то вы можете смотреть из глаз любого игрока или бота на уровне. Если вы играете в командную игру, то вы можете смотреть из глаз любого игрока вашей команды.
  • CheatView XXX - Используется для просмотра иры из глаз ботов другой комнады в Single Player игре.
  • Verbose - Показывает что думает бот, из которого вы в данный момент смотрите
  • KillAll XXX - Уничтожает всех объектов класса xxx включая подкласы.
  • Fly - Вы летаете по уровню
  • Walk - Возвращает в нормальное, "ходячее" состояние.
  • Ghost - Вы можете летать по уровню и проходить сквозь стены и предметы.
  • Loaded - Дает вам все оружие, кроме Redeemer'а.
  • AllAmmo - Дает 999 патронов для каждого имеющегося оружия
  • Invisible b - b=1 делает вас невидимым, b=0 - видимым
  • God - Бессмертие
  • BehindView b - b=1 - вид от третьего лица, b=0 - вид из глаз
  • SloMo f - Изменяет скорость игры. 1.0 - нормальная скорость, 2.0 - в два раза больше, 0.2 - в пять раз меньше.
  • Killpawns - Убивает всех живых объектов
  • Summon xxx - Добавляет актера класса xxx прямо перед вами. По умолчанию, актер должен находиться в packag'е Botpack. Если он находится в другом packag'е, то добавьте его перед названием класса: "summon unrealshare.vase".
  • RrememberSpot - Запомнить текужее местоположение игрока
  • ShowPath - Показать путь от текущего местоположения игрока к запомненной точке.