В этом разделе вы узнаете, как добавить в игровой процесс пользовательский визуальный эффект сердцебиения, сигнализирующий о местоположении игроков-объектов, стоящих неподвижно.
При слишком долгом бездействии игроков прячущейся команды на них воспроизводится визуальный эффект сердцебиения, уведомляющий команду охотников. Такой визуальный эффект регистрируется для каждого игрока прячущейся команды по мере их появления в игре.
Для реализации функций такой сигнализации мы будем использовать генераторы визуальных эффектов и язык Verse. Что сюда входит:
-
активация визуальных эффектов;
-
телепортация генератора визуальных эффектов к игрокам;
-
создание интерфейса, по которому члены прячущейся команды смогут определять, сколько им ещё двигаться, пока сигнал сердцебиения не исчезнет.
В этой инструкции описаны фрагменты кода Verse с пояснениями, как запустить игровую механику, необходимую для этого режима. Выполните следующие действия и скопируйте весь код из этой инструкции на шаге 6.
Подготовка

Мы настоятельно рекомендуем хранить ресурсы и устройства в папках упорядоченно, чтобы их легко было найти потом. Устройства можно сгруппировать по назначению, местоположению, типу или иному принципу.
Размещённые ресурсы можно помещать в создаваемые папки и акторы.
В приведённом выше gif-файле генератор визуальных эффектов перетаскивается в папку HeartBeatVFX прячущейся команды для систематизации хранения. Кроме того, можно нажать правую кнопку мыши и в появившемся меню выбрать команду Переместить в, чтобы выбрать папку, в которую следует переместить ресурс.
Используемые устройства:
Устройство «Генератор визуальных эффектов»

Создайте по одному генератору визуальных эффектов для каждого игрока. В момент, когда игроку понадобится визуальный эффект, генератор телепортируется в место расположения игрока. Если он больше не нужен, он будет скрыт до следующего раза.
Генераторы визуальных эффектов (ВЭ) в данном шаблоне используют эффекты Niagara для создания пользовательских ресурсов, показываемых в ходе игры. Ресурсы визуальных эффектов, описанные в данной инструкции, настроены на отображение сигналов сердцебиения, выдающих неподвижных игроков из прячущейся команды. Эффект появляется над объектами, остающимися неподвижными минимум 15 секунд.
В соответствующем разделе нашей документации Визуальные эффекты описано много способов создания эффекта сердцебиения. После этого такой пользовательский эффект сердцебиения, который вы создадите с помощью генератора визуальных эффектов, будет готов к использованию.
Попробуйте это проделать при размещении генератора визуальных эффектов. На панели Сведения выберите пользовательский эффект из выпадающего меню Пользовательский визуальный эффект. Чтобы выбранный ВЭ появился в окне просмотра, обязательно включите параметр Переопределить пользовательский визуальный эффект.

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

Параметр | Значение | Пояснение |
---|---|---|
Пользовательский визуальный эффект | HeartBeatVFX | Определяет пользовательскую частицу, которая будет использоваться вместо частицы из заранее подготовленного списка. |
Переопределить пользовательский визуальный эффект | True | Определяет, будут или нет использоваться визуальные эффекты разработчиков. |
Активно во время фазы | Только игровой процесс | Определяет, на каких этапах игры устройство будет активно. Включённый генератор визуальных эффектов будет воспроизводить выбранный эффект частиц. |
Воспроизведение эффектов сердцебиения в заданном местоположении
Выполните следующие действия, чтобы переместить генератор визуальных эффектов в Verse для включения и выключения воспроизведения эффекта сердцебиения на игроках прячущейся команды.
-
Создайте новый файл Verse в проекте под названием heartbeat.verse. Это не будет устройство Verse, так что его можно создать пустым.
-
Щёлкните два раза по созданному файлу Verse и добавьте следующие пути Verse для импорта.
using { /Fortnite.com/Characters } using { /Fortnite.com/Devices } using { /Fortnite.com/UI } using { /UnrealEngine.com/Temporary/SpatialMath } using { /UnrealEngine.com/Temporary/Diagnostics } using { /UnrealEngine.com/Temporary/UI } using { /Verse.org/Colors } using { /Verse.org/Simulation }
-
Этот код создаёт класс под названием
heartbeat_vfx
в heartbeat.verse. Классheartbeat_vfx
содержит структуру данных для отслеживания объектовvfx_spawner_device
для каждого игрока, а также функции для установки ВЭ в нужное положение или его сброса.log_heart_beat := class(log_channel){} # Эти сообщения используются для отображения (или скрытия) уведомления агенту прячущейся команды, когда ему необходимо начать двигаться, чтобы не допустить появления привязанного к нему эффекта сердцебиения. HeartBeatWarningMessage<localizes>(Time:int):message = "Сердцебиение через {Time} сек. Двигайтесь!" HeartBeatWarningClear<localizes>:message = "" # Этот класс предоставляет редактируемые свойства сердцебиения устройству Verse prop_hunt. heart_beat := class<concrete>(): Logger:log = log{Channel:=log_heart_beat} @editable # Время в секундах, до истечения которого агент прячущейся команды должен сдвинуться с места, чтобы сердцебиение не раскрыло его местоположение. MoveTime:float = 15.0 @editable # Время в секундах, остающееся до момента, когда появится предупреждение о сердцебиении. Эта величина не должна превышать величину HeartBeatTimer. WarningTime:float = 5.0 @editable # Массив устройств ВЭ «сердцебиение». По одному устройству на каждого из игроков. AgentVFX:[]heartbeat_vfx = array{} @editable # Устройство «Радио», используемое для воспроизведения звуковых эффектов сердцебиения (спецэффектов). SFXPlayer:radio_device = radio_device{} # Этот ассоциативный массив связывает интерфейс, с помощью которого отображается предупреждение о сердцебиении, с каждым агентом прячущейся команды. var WarningUI:[agent]heartbeat_warning_ui = map{} # Отслеживает количество игроков с активным сигналом сердцебиения, чтобы мы могли управлять устройством спецэффектов. var NumberOfHeartBeats:int = 0 # Настраивает для агента интерфейс, отображающий сердцебиение. SetUpUI(PropAgent:agent):void = if: not WarningUI[PropAgent] AsPlayer := player[PropAgent] PlayerUI := GetPlayerUI[AsPlayer] then: UIData:heartbeat_warning_ui = heartbeat_warning_ui{} UIData.CreateCanvas() PlayerUI.AddWidget(UIData.Canvas, player_ui_slot{ZOrder := 1}) if (set WarningUI[PropAgent] = UIData) {} # Активирует визуальный эффект «сердцебиение» и спецэффект для указанного игрока. Enable(PropAgent:agent, HeartBeatVFXData:heartbeat_vfx):void = if: # Получаем персонажа, используемого для поиска местонахождения агента прячущейся команды в сцене. Character := PropAgent.GetFortCharacter[] then: # Устанавливаем появление визуального эффекта «сердцебиение» в месте нахождения агента прячущейся команды. HeartBeatVFXData.Activate(Character.GetTransform()) # Увеличиваем количество сигналов сердцебиения; если сердцебиение воспроизводится первый раз, для его запуска нужно воспроизвести аудиофайл. set NumberOfHeartBeats += 1 if (NumberOfHeartBeats = 1) then SFXPlayer.Play() # Регистрируем агента прячущейся команды в устройстве «Аудиопроигрыватель», чтобы в месте его расположения воспроизводился звук сердцебиения. SFXPlayer.Register(PropAgent) else: Logger.Print("Персонаж, индекс или HeartBeatVFXData не обнаружены. Невозможно воспроизвести сердцебиение") # Убирает визуальный эффект «сердцебиение» и спецэффект для указанного агента прячущейся команды. Disable(PropAgent:agent, HeartBeatVFXData:heartbeat_vfx):void = Logger.Print("Отключение сердцебиения.") # Отключаем визуальные эффекты. HeartBeatVFXData.Deactivate() # Отменяем регистрацию агента прячущейся команды в устройстве «Аудиопроигрыватель», чтобы звук сердцебиения прекратил воспроизводиться. SFXPlayer.Unregister(PropAgent) # Уменьшаем количество сигналов сердцебиения. Значение этого счётчика не должно быть меньше 0. set NumberOfHeartBeats -= 1 if (NumberOfHeartBeats < 0) then set NumberOfHeartBeats = 0 # Убирает все визуальные эффекты «сердцебиение» и спецэффекты, использовавшиеся для указанных агентов прячущейся команды. DisableAll():void = Logger.Print("Отключение всех сигналов сердцебиения.") # Проходим по всем визуальным эффектам и меняем их значения на 0,0,0. for (HeartBeatVFXDevice : AgentVFX): HeartBeatVFXDevice.Deactivate() # Отменяем регистрацию всех игроков в устройстве воспроизведения сердцебиения. SFXPlayer.UnregisterAll() # Сбрасываем счётчик сигналов сердцебиения до 0 set NumberOfHeartBeats = 0 # Класс heartbeat_warning_ui содержит структуру данных для отслеживания рабочей области интерфейса и text_block для каждого игрока, а также функцию создания новой рабочей области интерфейса для предупреждений о сердцебиении. heartbeat_warning_ui := class: var Canvas:canvas = canvas{} var Text:text_block = text_block{} # Создаёт рабочую область интерфейса для предупреждений. CreateCanvas():void = set Text = text_block{DefaultTextColor := NamedColors.White, DefaultShadowColor := NamedColors.Black} set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors{Minimum := vector2{X := 0.5, Y := 0.75}, Maximum := vector2{X := 0.5, Y := 0.75}} Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0} Alignment := vector2{X := 0.5, Y := 1.0} SizeToContent := true Widget := Text
-
Этот код создаёт метод
Activate()
в классеheartbeat_vfx
, который принимает аргумент преобразования и переносит генератор визуальных эффектов в такое преобразование (transform
).# Класс heartbeat_vfx содержит структуру данных для отслеживания корня ВЭ и объектов vfx_spawner_device для каждого игрока, а также функции для установки ВЭ в нужное положение или его сброса. heartbeat_vfx := class<concrete>: @editable # Генератор ВЭ для каждого сигнала «сердцебиение». VFXDevice:vfx_spawner_device = vfx_spawner_device{} # Данное смещение используется для размещения сигнала сердцебиения над головой агента прячущейся команды. HeartBeatVFXOffset:vector3 = vector3{X := 0.0, Y := 0.0, Z := 110.0} # Задаёт положение визуального эффекта сердцебиения и затем включает его. Activate(Transform:transform):void = VFXPosition := Transform.Translation + HeartBeatVFXOffset if (VFXDevice.TeleportTo[VFXPosition, Transform.Rotation]): VFXDevice.Enable()
-
Этот код создаёт метод
Deactivate()
в классеheartbeat_vfx
, который отключает генератор визуальных эффектов, и визуальные эффекты сердцебиения больше не отображаются.# Класс heartbeat_vfx содержит структуру данных для отслеживания корня ВЭ и объектов vfx_spawner_device для каждого игрока, а также функции для установки ВЭ в нужное положение или его сброса. heartbeat_vfx := class<concrete>: @editable # Генератор ВЭ для каждого сигнала «сердцебиение». VFXDevice:vfx_spawner_device = vfx_spawner_device{} # Данное смещение используется для размещения сигнала сердцебиения над головой агента прячущейся команды. HeartBeatVFXOffset:vector3 = vector3{X := 0.0, Y := 0.0, Z := 110.0} # Задаёт положение визуального эффекта «сердцебиение», а затем включает его. Activate(Transform:transform):void = VFXPosition := Transform.Translation + HeartBeatVFXOffset if (VFXDevice.TeleportTo[VFXPosition, Transform.Rotation]): VFXDevice.Enable() # Отключает визуальный эффект, и сердцебиение больше не отображается. Deactivate():void = VFXDevice.Disable()
Показать предупреждение о сердцебиении игроку
Далее описаны шаги по индивидуальной настройке интерфейса с текстовым блоком, который будет отображать предупреждение о сердцебиении. Посмотрите статью Внутриигровые пользовательские интерфейсы, чтобы узнать, как создавать пользовательские интерфейсы и другие элементы интерфейса в Verse.
-
С помощью двух следующих констант настраивается текст, отображаемый для игроков прячущейся команды в разные моменты времени во время игры.
-
Константа
HeartBeatWarningMessage
представляет собой функцию, которая принимает типint
, а возвращает типmessage
. Этот тип используется в элементах интерфейса, так как его можно локализовать. Это текст, который видят игроки в момент, когда им нужно начать двигаться, иначе их местоположение может быть выдано эффектом сердцебиения. -
Константа
HeartBeatWarningClear
представляет собой пустое сообщениеmessage
, которое отобразится для того, чтобы игроки больше не видели предупреждающее сообщение.
# Эти сообщения используются для отображения (или скрытия) уведомления агенту прячущейся команды, когда ему необходимо начать двигаться, чтобы не допустить появления привязанного к нему эффекта сердцебиения. HeartBeatWarningMessage<localizes>(Time:int):message = "Сердцебиение через {Time} сек. Двигайтесь!" HeartBeatWarningClear<localizes>:message = ""
-
-
Создайте новый класс под названием
heartbeat_warning_ui
в heartbeat.verse. Классheartbeat_warning_ui
содержит структуру данных для отслеживания рабочей области интерфейса иtext_block
для каждого игрока, а также функцию создания новой рабочей области интерфейса для предупреждений о сердцебиении.# Класс heartbeat_warning_ui содержит структуру данных для отслеживания рабочей области интерфейса и text_block для каждого игрока, а также функцию создания новой рабочей области интерфейса для предупреждений о сердцебиении. heartbeat_warning_ui := class: var Canvas:canvas = canvas{} var Text:text_block = text_block{} # Создаёт рабочую область интерфейса для предупреждений. CreateCanvas():void = set Text = text_block{DefaultTextColor := NamedColors.White, DefaultShadowColor := NamedColors.Black} set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors{Minimum := vector2{X := 0.5, Y := 0.75}, Maximum := vector2{X := 0.5, Y := 0.75}} Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0} Alignment := vector2{X := 0.5, Y := 1.0} SizeToContent := true Widget := Text
Управление эффектами сердцебиения
Далее описано, как создать диспетчер эффектов сердцебиения.
-
Показанный ниже код создаёт класс
heart_beat
в heartbeat.verse. # Этот класс предоставляет редактируемые свойства эффекта сердцебиения устройству prop_hunt и управляет эффектами сердцебиения.log_heart_beat := class(log_channel){} # Этот класс предоставляет редактируемые свойства сердцебиения устройству prop_hunt. heart_beat := class<concrete>(): Logger:log = log{Channel:=log_heart_beat} @editable MoveTime:float = 15.0
- Этот класс добавляет следующие редактируемые свойства в класс
heart_beat
.-
Этот код контролирует время в секундах, до истечения которого агент прячущейся команды должен сдвинуться с места, чтобы эффект сердцебиения не выдал его местоположение.
@editable MoveTime:float = 15.0
-
Этот код управляет временем в секундах, остающимся до момента появления на экране текста, предупреждающего члена прячущейся команды о необходимости начать двигаться, чтобы не появился эффект сердцебиения.
@editable WarningTime:float = 5.0
-
Данный код представляет собой массив устройств ВЭ «сердцебиение». По одному устройству на каждого из игроков.
@editable AgentVFX:[]heartbeat_vfx = array{}
-
В этом коде устройство «Радио» используется для воспроизведения звуковых эффектов сердцебиения (спецэффектов).
@editable SFXPlayer:radio_device = radio_device{}
-
-
-
Этот код связывает интерфейс, с помощью которого отображается предупреждение о сердцебиении, с каждым агентом прячущейся команды.
# Этот ассоциативный массив связывает интерфейс, с помощью которого отображается предупреждение о сердцебиении, с каждым агентом прячущейся команды. var WarningUI:[agent]heartbeat_warning_ui = map{}
-
Данный код отслеживает количество игроков с активным сигналом сердцебиения, чтобы можно было управлять устройством спецэффектов.
# Отслеживает количество игроков с активным сигналом сердцебиения, чтобы мы могли управлять устройством спецэффектов. var NumberOfHeartBeats:int = 0
-
Этот код показывает интерфейс с предупреждением игрокам.
# Настраивает для агента интерфейс, отображающий сердцебиение. SetUpUI(PropAgent:agent):void = if: not WarningUI[PropAgent] AsPlayer := player[PropAgent] PlayerUI := GetPlayerUI[AsPlayer] then: UIData:heartbeat_warning_ui = heartbeat_warning_ui{} UIData.CreateCanvas() PlayerUI.AddWidget(UIData.Canvas, player_ui_slot{ZOrder := 1}) if (set WarningUI[PropAgent] = UIData) {}
-
Этот код активирует визуальные (ВЭ) и звуковые эффекты (спецэффекты) для указанного игрока.
# Активирует визуальный эффект «сердцебиение» и спецэффект для указанного игрока. Enable(PropAgent:agent, HeartBeatVFXData:heartbeat_vfx):void = if: # Получаем персонажа, используемого для поиска местонахождения агента прячущейся команды в сцене. Character := PropAgent.GetFortCharacter[] then: # Устанавливаем появление визуального эффекта «сердцебиение» в месте нахождения агента прячущейся команды. HeartBeatVFXData.Activate(Character.GetTransform()) # Увеличиваем количество сигналов сердцебиения; если сердцебиение воспроизводится первый раз, для его запуска нужно воспроизвести аудиофайл. set NumberOfHeartBeats += 1 if (NumberOfHeartBeats = 1) then SFXPlayer.Play() # Регистрируем агента прячущейся команды в устройстве «Аудиопроигрыватель», чтобы в месте его нахождения воспроизводился звук сердцебиения. SFXPlayer.Register(PropAgent) else: Logger.Print("Персонаж, индекс или HeartBeatVFXData не обнаружены. Невозможно воспроизвести сердцебиение")
-
Этот код создаёт один метод для отключения ВЭ и спецэффекта для одного игрока и ещё один — для их отключения для всех игроков.
# Убирает визуальный эффект «сердцебиение» и спецэффект для указанного агента прячущейся команды. Disable(PropAgent:agent, HeartBeatVFXData:heartbeat_vfx):void = Logger.Print("Отключение сердцебиения.") # Отключаем визуальные эффекты. HeartBeatVFXData.Deactivate() # Отменяем регистрацию агента прячущейся команды в устройстве «Аудиопроигрыватель», чтобы звук сердцебиения прекратил воспроизводиться. SFXPlayer.Unregister(PropAgent) # Уменьшаем количество сигналов сердцебиения. Значение этого счётчика не должно быть меньше 0. set NumberOfHeartBeats -= 1 if (NumberOfHeartBeats < 0) then set NumberOfHeartBeats = 0 # Убирает все визуальные эффекты «сердцебиение» и спецэффекты, использовавшиеся для указанных агентов прячущейся команды. DisableAll():void = Logger.Print("Отключение всех сигналов сердцебиения.") # Проходим по всем визуальным эффектам и меняем их значения на 0,0,0. for (HeartBeatVFXDevice : AgentVFX): HeartBeatVFXDevice.Deactivate() # Отменяем регистрацию всех игроков в устройстве воспроизведения сердцебиения. SFXPlayer.UnregisterAll() # Сбрасываем счётчик сигналов сердцебиения до 0 set NumberOfHeartBeats = 0