Поведение неигрового персонажа определяется его сценарием поведения. Сценарий поведения определяет действия персонажей в мире, например куда идти, с кем сражаться и как взаимодействовать с другими персонажами. Такие персонажи, как охранники и дикие животные, могут обладать дополнительными поведениями, такими как восприятие, насторожённость и возможность найма или приручения.
Поведение неигрового персонажа — это определяемый пользователем сценарий Verse, который добавляет дополнительную функциональность к существующему поведению неигрового персонажа. API npc_behavior позволяет определить код, который будет выполняться, когда неигровой персонаж будет появляться или исчезать: его можно использовать для создания пользовательских персонажей, таких как медики, продавцы или боссы. Поведения неигровых персонажей наследуются от абстрактного класса npc_behavior, поэтому нужно импортировать модуль /Fortnite.com/AI, который и предназначен для данных целей.
Чтобы запустить сценарий поведения неигрового персонажа, его необходимо привязать к определению неигрового персонажа. То, как сценарий поведения неигрового персонажа взаимодействует с определением персонажа, зависит от типа неигрового персонажа. Неигровым персонажам пользовательского типа для выполнения действий требуется сценарий поведения, в то время как неигровые персонажи типа «Охранник» и «Дикое животное» реализуют собственное поведение по умолчанию, даже если их сценарий поведения не задан. Дополнительную информацию о создании определения неигрового персонажа и различных типах персонажей см. на странице «Определение персонажа».
В этом уроке мы рассмотрим основы создания сценария поведения неигрового персонажа и научимся создавать неигровых персонажей и направлять их к цели.
Создание нового сценария поведения неигрового персонажа
Выполните следующие шаги, чтобы написать сценарий поведения неигрового персонажа в UEFN, который создаёт охранника и заставляет его патрулировать по маршруту между двумя точками.
Откройте проект в UEFN, а затем в строке меню выберите Verse > Проводник Verse.
В проводнике Verse нажмите правой кнопкой мыши по названию вашего проекта и выберите Добавить новый файл Verse в проект, чтобы открыть окно Создать сценарий Verse.
В окне «Создать сценарий Verse» нажмите Поведение неигрового персонажа, чтобы выбрать его в качестве шаблона.
Добавьте название для поведения своего неигрового персонажа, изменив текст в поле Имя поведения неигрового персонажа на название вашего устройства. В этом примере для устройства задано название my_first_npc_behavior.
Нажмите Создать, чтобы создать файл Verse.
В проводнике Verse дважды нажмите на файл Verse, чтобы открыть его в Visual Studio Code.
Сохраните свой код, скомпилируйте его и создайте новое определение неигрового персонажа. Дополнительную информацию о создании неигрового персонажа см. на странице «Определение персонажа».
Назначьте свой сценарий
my_first_behaviorв качестве поведения Verse в новом определении персонажа.Нажмите «Запустить сеанс» на панели инструментов UEFN, чтобы выполнить игровой тест уровня. В игровом тесте уровня персонажи, созданные вашим генератором неигровых персонажей, должны выбрать случайную точку рядом с местом своего появления и двигаться к ней. Когда они достигнут этой точки, они должны подождать определённое время и вернуться к исходной точке. Если вы включили настройку Отладочное рисование Verse в устройстве «Настройки острова», начнут отображаться нарисованные стрелки, показывающие, куда смотрит персонаж, а также поля, обозначающие точку, к которой он движется.
Navigatable
Вы можете использовать API Navigatable, чтобы направлять персонажей к определённым целям, а также для выполнения таких задач, как патрулирование, охрана точки или следование за другим персонажем. Неигровые персонажи типа «Охранник» могут делать это с помощью узлов маршрута патрулирования ИИ, но вы можете использовать код Verse, чтобы сделать эти функции доступными персонажу любого типа и избежать размещения на уровне дополнительных устройств. Интерфейс navigatable персонажа позволяет перемещать персонажей к цели navigation_target, которую можно создать на основе agent или position. Навигационный интерфейс могут использовать пользовательские неигровые персонажи, охранники и дикие животные. Чтобы получить интерфейс navigatable персонажа, сначала нужно получить ссылку на его fort_character, для чего можно вызвать GetFortCharacter[].
# Get the Navigatable Interface, this allows you to tell it to move.
Navigatable := Character.GetNavigatable[]
В примере шаблона код выбирает положение исходя из случайного смещения относительно места, где появился персонаж, и сохраняет его в переменной GoToPoint. Затем он создаёт цель navigation_target на основе как GotToPoint, так и точки появления персонажа.
# Create a random offset from the spawn point to walk toward.
GoToPoint := NPCSpawnPoint + vector3{X := GetRandomFloat(-DistanceFromSpawnPtToMove,DistanceFromSpawnPtToMove),
Y := GetRandomFloat(-DistanceFromSpawnPtToMove,DistanceFromSpawnPtToMove),
Z := 0.0 }
if(ShowAIDebug?):
Print(my_first_npc_behavior_message_module.OnNavigateBeginMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)
# Create a navigation target from these two positions that the navigation interface can use.
NavTargetStart := MakeNavigationTarget(GoToPoint)
Функция NavigateTo() возвращает результат navigation_result типа enum, который содержит информацию о том, достиг ли персонаж своей цели navigation_target. Исходя из значения navigation_result вы можете задавать поведение персонажей в зависимости от того, достигли ли они своей цели.
# Check to see if something has interfered with the NPC reaching the intended location and print a
# message to the output log.
if (NavResultGoTo <> navigation_result.Reached):
if(ShowAIDebug?):
Print(my_first_npc_behavior_message_module.OnNavigateErrorMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)
else:
# Once it arrives at its location, wait for this duration in seconds
Navigatable.Wait(?Duration := MoveToWaitDuration)Дополнительную информацию о том, как персонажи перемещаются по миру, и о визуализации различных зон, куда могут перемещаться персонажи, см. на странице Навигационная сетка.
Киберциклоп
Когда персонажи выполняют действия, они смотрят на определённые цели. Конкретная цель, на которую смотрит персонаж, называется его фокусом. Персонажи фокусируются на персонаже, с которым они разговаривают, на цели, которую атакуют, или на месте, куда направляются. Интерфейс focus_interface позволяет указывать конкретные цели, на которых должны фокусироваться персонажи. Интерфейс фокуса могут использовать пользовательские неигровые персонажи, охранники и дикие животные. Функция MaintainFocus() фокусирует персонажа на цели, которая может быть либо положением vector3, либо агентом agent. Интерфейс focus_interface является частью интерфейса fort_character, и получить его можно с помощью GetFocusInterface[].
# Get the Focus Interface, this allows you to tell it to look at something or somewhere.
Focus := Character.GetFocusInterface[]
В примере шаблона, после того как персонаж начинает возвращаться в исходную точку, в коде выполняется функция MaintainFocus(), чтобы заставить его сфокусироваться на предыдущей цели navigation_target. Это заставляет персонажа идти назад и смотреть обратно, возвращаясь в исходную точку.
# Leveraging concurrency to wait until the NPC reaches its destination, while the calls to look back at its origin point
# and drawing a debug arrow never completes, continuing, ensures only the NavigateTo can win the race.
NavResultGoToNext := race:
# Move back to its starting position.
Navigatable.NavigateTo(NavTargetEnd)
# Sets NPC to look at its previous position which will make it walk backwards.
# This is meant to show the utility of the focus interface.
block:
Focus.MaintainFocus(GoToPoint)
Возможность создать привязку
Когда охранники охраняют цель, нужно обеспечить, чтобы они оставались в зоне вокруг цели и не отходили слишком далеко. fort_leashable — это интерфейс, специфичный для неигрового персонажа типа «Охранник», который позволяет указать радиус вокруг цели, за который охранники не будут выходить при патрулировании. Вы можете привязать охранников к определённым позициям или другим неигровым персонажам, и охранники будут обновлять своё положение, чтобы оставаться рядом с целью привязки, если она переместится. Обратите внимание, что в настоящее время неигровые персонажи типа «Пользовательский» и «Дикое животное» не могут использовать интерфейс fort_leashable. Интерфейс fort_leashable вы можете получить с помощью функции GetFortLeashable[].
# Get the Leash Interface, which lets you confine a guard to a certain area.
Leashable := Character.GetFortLeashable[]
Вы можете привязать охранников к позициям или другим агентам, например, чтобы охранять точку захвата или защищать важного неигрового персонажа. У каждой привязки есть параметры InnerRadius и OuterRadius, которые определяют, насколько близко и далеко (в сантиметрах) охранникам нужно держаться относительно цели привязки. В примере шаблона не используется интерфейс leashable, но он может пригодиться при создании собственных неигровых персонажей-охранников.
# Leash the guard to a position so they stay between 500 and 1000
# cm of the position they're leashed to
Leashable.SetLeashPosition(NPCSpawnPoint, InnerRadius := 500.0, OuterRadius := 1000.0)
# Leash the guard to an agent so they stay between 500 and 1000
# cm of the agent they're leashed to
Leashable.SetLeashAgent(AgentToFollow, InnerRadius := 500.0, OuterRadius := 1000.0)
# Clear all leashes on the guard
Leashable.ClearLeash()
Отладочное рисование
В начале файла шаблона определён выделенный канал для отладочного рисования. Вы можете использовать отладочное рисование, чтобы визуализировать определённые игровые данные в целях тестирования. Например, вы можете визуализировать поле зрения вашего персонажа или нарисовать форму вокруг места, куда он направляется. Чтобы визуализировать отладочные формы, необходимо включить Отладочное рисование Verse на вкладке Отладка в Настройках острова. На опубликованных островах эти формы отображаться не будут. Канал в начале файла позволяет скрыть, показать или удалить все отладочные формы в канале с помощью одного метода.
# Create a dedicated debug channel to draw to for this behavior
npc_debug_draw := class(debug_draw_channel) {}
Шаблон класса new_npc_behavior определяет несколько значений, используемых для визуализации и перемещения.
MoveToWaitDurationопределяет, сколько времени в секундах персонаж ожидает в определённой точке, прежде чем начать перемещаться.Verse# How long to wait in seconds after the NPC navigates to a point before moving on. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5}, MaxValue:=option{10.0} MoveToWaitDuration:float = 5.0DistanceFromSpawnPtToMoveопределяет диапазон случайного смещения относительно точки появления, в котором может перемещаться персонаж.Verse# The negative min and absolute max x & y coordinate offset in centimeters to tell the NPC to move to @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.0} DistanceFromSpawnPtToMove:float = 1500.0Логическая переменная
ShowAIDebugпозволяет переключать отрисовку отладочных форм из редактора.Verse# Whether to draw debug to the NPC channel when Verse Debug Draw is enabled in Island Settings. @editable: Categories:=array{my_first_npc_behavior_message_module.SettingsCategory} ShowAIDebug:logic = trueЗначение с плавающей запятой
AIDebugDrawTimeпозволяет указать время, в течение которого будет отрисовываться отладочная форма местоположения.Verse# How long in seconds to render the debug draw location and print text. # It is recommended to keep this in sync with MoveToWaitDuration otherwise the print will not be shown if a previous message is displayed. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5} AIDebugDrawTime:float = 5.0Значение с плавающей запятой
LookAtDebugDrawDurationпозволяет указать, как долго будет отрисовываться отладочная стрелка направления взгляда.Verse# How long in seconds to render the look at arrow's debug draw. LookAtDebugDrawDuration:float = 0.5Канал
DebugDrawNPCопределяет экземпляр отладочного рисования и использует канал, определённый в начале файла.Verse# How long in seconds to render the look at arrow's debug draw. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5} LookAtDebugDrawDuration:float = 0.5Наконец,
VerticalOffsetToNPCHeadопределяет смещение головы неигрового персонажа относительно его таза, чтобы определить точку, из которой будет рисоваться отладочная стрелка направления взгляда. Без такого смещения отладочная стрелка направления взгляда отрисовывалась бы из центра неигрового персонажа.Verse# Used for specifying a point offset from the NPC pelvis to the head to draw the look at arrow from. VerticalOffsetToNPCHead<private>:float = 55.0
В шаблоне класса new_npc_behavior имеются две функции, которые рисуют отладочные формы. Функция DrawDebugLocation() отрисовывает крупную точку в указанной позиции в течение длительности LookAtDebugDrawDuration.
# This function draws a box around a specified position for a finite amount of time.
# NOTE: To see this in game, Verse Debug Draw must be enabled in Island Settings.
DrawDebugLocation(Location:vector3):void =
DebugDrawNPC.DrawPoint( Location,
?Color := NamedColors.SteelBlue,
?Thickness := 100.0,
?DrawDurationPolicy := debug_draw_duration_policy.FiniteDuration,
?Duration := AIDebugDrawTime )
Функция DrawDebugLookAt() визуализирует, куда смотрит персонаж, рисуя стрелку от головы агента к точке фокуса его взгляда.
# This function draws an arrow from the Agent's head to its look at point every half a second.
# NOTE: To see this in game, Verse Debug Draw must be enabled in Island Settings.
DrawDebugLookAt(Character:fort_character, LookAtPoint:vector3)<suspends>:void=
loop:
DebugDrawNPC.DrawArrow( Character.GetTransform().Translation + vector3{ Z := VerticalOffsetToNPCHead},
LookAtPoint,
?ArrowSize := 50.0,
?Color := NamedColors.Yellow,
?Thickness := 5.0,
?DrawDurationPolicy := debug_draw_duration_policy.FiniteDuration,
Добавление персонажа на уровень
Теперь, когда вы разобрались со сценарием поведения неигрового персонажа, самое время создать персонажа и использовать сценарий на острове. Следующий рабочий процесс предназначен для персонажей типа «Охранник», однако сценарий поведения неигрового персонажа также будет работать для персонажей типа «Пользовательский» и «Дикое животное».
Создайте новое определение неигрового персонажа, назвав его MyFirstCharacterDefinition. Теперь нажмите на это определение персонажа, чтобы открыть экран Определение персонажа.
На экране Определение персонажа измените следующие свойства:
В Типе неигрового персонажа для параметра Тип задайте значение Охранник. Интерфейс охранника позволяет получать доступ к функциям, специфичным для персонажа-охранника, например к событиям, когда охранник переходит в состояние тревоги или настороженности, а также даёт возможность нанимать охранников для использования в качестве союзников. Также охранники могут использовать оружие, в то время как персонажи типа «Пользовательский» и «Дикое животное» в настоящее время не могут этого делать. Вы также можете изменить имя своего персонажа во вкладке Имя.
В разделе Поведение неигрового персонажа установите для параметра Поведение значение Поведение Verse. Затем установите
my_first_npc_behaviorв качестве Сценария поведения неигрового персонажа. Ваш персонаж по-прежнему сможет обращаться к функциям интерфейса охранника, но будет использовать ваш сценарий Verse, чтобы решать, что делать при возникновении событийOnBeginиOnEnd.На вкладке Модификаторы в разделе Модификатор появления охранника нажмите на вкладку Косметический предмет, чтобы изменить внешний вид персонажа. Вы можете выбрать один из существующих косметических предметов или включить Перенос косметических предметов персонажа, чтобы использовать собственную модель. Обратите внимание, использовать перенос косметических предметов персонажа могут только охранники и пользовательские персонажи, а дикие животные не могут. Дополнительную информацию о модификаторах персонажей и о том, какие из них применяются к различным типам персонажей, см. на странице «Определение неигрового персонажа».
Во вкладке Модификаторы нажмите на Добавить элемент, чтобы добавить новый модификатор к своему персонажу. Измените тип нового модификатора на Модификатор инвентаря. Обратите внимание, что модификатор инвентаря могут использовать только охранники.
В разделе Модификатор инвентаря нажмите Добавить элемент, чтобы добавить новый предмет в инвентарь своего персонажа. Задайте в Определении предмета оружие, предмет или что-нибудь ещё, что должно быть у вашего персонажа. Вы можете добавить в инвентарь своего персонажа несколько предметов, и ваш персонаж будет использовать оружие для боя, предметы для лечения и т. д.
Во вкладке Модификаторы нажмите на Добавить элемент, чтобы добавить новый модификатор к своему персонажу. Измените тип нового модификатора на Модификатор интерфейса.
В разделе Модификатор интерфейса нажмите на вкладку Имя, чтобы изменить имя своего персонажа. Имя вашего персонажа будет отображаться над его головой.
Сохраните определение неигрового персонажа. В Каталоге ресурсов перетащите определение неигрового персонажа на уровень. При этом будет автоматически создан новый генератор неигровых персонажей и ему будет присвоено определение вашего персонажа.
Выберите свой генератор неигровых персонажей. В окне Структура в разделе Пользовательские настройки:
Установите Кол-во появлений равным 20. Вам понадобится несколько охранников, так что не ограничивайте себя.
Нажмите Запустить сеанс на панели инструментов UEFN, чтобы выполнить игровой тест уровня. Во время игрового теста ваш персонаж должен появиться и начать патрулирование по маршруту между своей исходной точкой и случайной точкой рядом с ней, а также вступать в бой со всеми врагами, которые попадутся на пути.
Самостоятельная работа
Пройдя это руководство, вы узнали, как написать сценарий поведения неигрового персонажа, чтобы создавать собственных персонажей. Чтобы узнать больше и научиться создавать персонажей и сценарии разных типов, ознакомьтесь с некоторыми уроками по поведению неигровых персонажей, перечисленными ниже.