В этой игре с тремя командами команда захватчиков играет уникальную роль. Захватчики действуют скрытно и начинают игру невидимыми. Они появляются с винтовкой со скользящим затвором, наносящей большой урон, и могут устранять соперников из укрытия, пробираясь к базе защитников. Захватчики не всегда невидимы: если по ним нанести удар, режим невидимки временно деактивируется и они начинают мерцать.
В этом уроке вы также узнаете, как активировать мерцание одного или всех захватчиков в команде, если одному из них нанесён урон. Мерцание всей команды создаёт для захватчиков серьёзные проблемы, однако это стимул для того, чтобы играть осторожней.
Ниже приведён порядок настройки режима невидимости для захватчиков при появлении.
Создание диспетчера невидимости
- Создайте в Проводнике Verse новое устройство Verse invisibility_manager и перетащите его на уровень.
- В начале файла
invisibility_manager
добавьте строкуusing { /Fortnite.com/Characters }
, чтобы получитьfort_character
, соответствующий игроку.using { /Fortnite.com/Devices } using { /Fortnite.com/Characters } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics }
- В определении класса
invisibility_manager
добавьте следующие поля:- Редактируемый массив точек появления игроков
PlayerSpawners
. Он позволит отслеживать точки появления игроков для захватчиков и будет использоваться для того, чтобы делать захватчиков невидимыми при появлении.invisibility_manager := class(creative_device): Logger:log = log{Channel := triad_invisibility_log_channel} # Массив точек появления игроков для команды захватчиков @editable PlayersSpawners:[]player_spawner_device = array{}
- Редактируемая логическая переменная
IsVisibilityShared
. Определяет, должны ли при нанесении урона одному из захватчиков мерцать все захватчики или же должен мерцать только захватчик, получивший урон.# Массив точек появления игроков для команды захватчиков @editable PlayersSpawners:[]player_spawner_device = array{} # Распространяется ли видимость захватчика на других участников команды. @editable IsVisibilityShared:logic = true
- Редактируемые числа с плавающей запятой
VulnerableSeconds
иFlickerRateSeconds
. Первое определяет продолжительность мерцания захватчиков после получения урона, а второе — периодичность воспроизведения анимации мерцания.# Распространяется ли видимость захватчика на других участников команды. @editable IsVisibilityShared:logic = true # Как долго захватчики остаются видимыми после получения урона. @editable VulnerableSeconds:float = 3.0 # Как часто захватчики мерцают при получении урона. @editable FlickerRateSeconds:float = 0.4
- Массив переменных типа team с именем
Teams
. Он пригодится, чтобы проверить, является ли игрок захватчиком.# Как часто захватчики мерцают при получении урона. @editable FlickerRateSeconds:float = 0.4 # Массив всех команд в игре. var Teams:[]team = array{}
- Ассоциативный массив переменных
PlayerVisibilitySeconds
, связывающийagent
со значением типаfloat
. Сопоставляет отдельные агенты с оставшимся временем мерцания в секундах после получения урона игроком.var Teams:[]team = array{} # Массив всех команд в игре. var Teams:[]team = array{} # Ассоциативный массив, содержащий оставшееся время мерцания в секундах для каждого игрока. var PlayerVisibilitySeconds:[agent]float = map{}
- Редактируемый массив точек появления игроков
- Добавьте в
OnBegin()
оператор записи в журнал, чтобы проверить, что устройство запустилось. Нужно обеспечить запускinvisibility_manager
после распределения игроков по командам с помощью сценарияtriad_infiltration_game
, чтобы не сделать невидимыми игроков из неподходящих команд. Для этого нужно запускатьinvisibility_manager
изtriad_infiltration_game
, а не включать этот код вOnBegin()
.OnBegin<override>()<suspends>:void= # Ждать, пока состав команд выровняется, чтобы подписаться на события, которые делают игроков невидимыми. Logger.Print("Ожидаем завершения выравнивания состава команд…")
- Добавьте новый метод
OnPlayerSpawn()
в определение классаinvisibility_manager
. Необходимо, чтобы захватчики становились невидимыми всякий раз, когда они появляются, поэтому сначала нужно вызвать эту функцию.# Обрабатывает появление игрока в точке появления захватчиков OnPlayerSpawn(SpawnedAgent:agent):void= Logger.Print("Игрок только что появился в точке появления захватчиков!")
- В функции
OnPlayerSpawn()
получитеfort_character
, связанный с появившимся агентом, с помощьюGetFortCharacter[]
и сохраните его в переменнойFortCharacter
. Также нужно получить команду появившегося агента с помощьюGetTeam[]
и сохранить её в переменнойCurrentTeam
.# Обрабатывает появление игрока в точке появления захватчиков OnPlayerSpawn(SpawnedAgent:agent):void= Logger.Print("Игрок только что появился в точке появления захватчиков!") if: FortCharacter:fort_character = SpawnedAgent.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[SpawnedAgent]
- Проверьте, совпадает ли
CurrentTeam
с первой командой в массивеTeams
(командой захватчиков). Если да, то этот агент является захватчиком и вы можете вызватьHide()
дляFortCharacter
этого агента. Это позволит сделать агент невидимым при появлении. Ваша функцияOnPlayerSpawn()
должна выглядеть следующим образом:# Обрабатывает появление игрока в точке появления захватчиков OnPlayerSpawn(SpawnedAgent:agent):void= Logger.Print("Игрок только что появился в точке появления захватчиков!") if: FortCharacter:fort_character = SpawnedAgent.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[SpawnedAgent] Teams[0] = CurrentTeam Logger.Print("Игрок появился в качестве захватчика, делаем его невидимым") then: FortCharacter.Hide()
- В функции
- Добавьте новый метод
StartInvisibilityManager()
в определение классаinvisibility_manager
. Эта функция принимает массив командAllTeams
типа team, массив игроковAllPlayers
типа player и ссылку на команду захватчиков типаteam
. Вы будете вызвать её из сценарияtriad_infiltration_game
, чтобы запустить логикуinvisibility_manager
, поэтому эта функция должна иметь спецификатор<public>
, чтобы сценарийtriad_infiltration_game
мог к ней обращаться.# Запускает логику диспетчера невидимости. Вызывается из класса triad_infiltration после завершения выравнивания состава команд StartInvisibilityManager<public>(AllTeams:[]team, AllPlayers:[]player, Infiltrators:team):void= Logger.Print("Сценарий установки невидимости запущен!")
- В
StartInvisibilityManager()
:- Присвойте массиву
Teams
значение массиваAllTeams
.# Запускает логику диспетчера невидимости. Вызывается из класса triad_infiltration после завершения выравнивания состава команд StartInvisibilityManager<public>(AllTeams:[]team, Players:[]player, Infiltrators:team):void= Logger.Print("Сценарий установки невидимости запущен!") set Teams = AllTeams
- В цикле
for
подпишите каждую точку появления игрока вPlayerSpawners
на функциюOnPlayerSpawn()
.for(PlayerSpawner:PlayersSpawners): PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn)
- В момент запуска сценария нужно найти всех захватчиков и сделать их невидимыми. Также нужно создать для них запись в ассоциативном массиве
PlayerVisibilitySeconds
. Она пригодится позже для отслеживания продолжительности мерцания каждого захватчика, получившего урон. Точно так же, как в случае сOnPlayerSpawn()
, получитеfort_character
иteam
для каждого игрока.for(PlayerSpawner:PlayersSpawners): PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn) # Для каждого игрока, появившегося в команде захватчиков, создать отдельный экземпляр функции # OnInfiltratorDamaged. Затем сделать его персонаж невидимым. for(TeamPlayer:AllPlayers): if: FortCharacter:fort_character = TeamPlayer.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]
- Проверьте, совпадает ли
CurrentTeam
с командойInfiltrators
, которую вы передали в эту функцию. Если да, задайте для ключа игрока вPlayerVisibilitySeconds
значение0.0
.for(TeamPlayer:AllPlayers): if: FortCharacter:fort_character = TeamPlayer.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer] Logger.Print("Текущая команда этого игрока определена") Infiltrators = CurrentTeam set PlayerVisibilitySeconds[TeamPlayer] = 0.0 Logger.Print("Игрок добавлен в PlayerVisibilitySeconds")
- Наконец, сделайте игрока невидимым, вызвав
Hide()
дляFortCharacter
игрока.StartInvisibilityManager
должен выглядеть следующим образом:# Запускает логику диспетчера невидимости. Вызывается из класса triad_infiltration после завершения выравнивания состава команд StartInvisibilityManager<public>(AllTeams:[]team, Players:[]player, Infiltrators:team):void= Logger.Print("Сценарий установки невидимости запущен!") set Teams = AllTeams for(PlayerSpawner:PlayersSpawners): PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn) # Для каждого игрока, появившегося в команде захватчиков, создать отдельный экземпляр функции # OnInfiltratorDamaged. Затем сделать его персонаж невидимым. for(TeamPlayer:AllPlayers): if: FortCharacter:fort_character = TeamPlayer.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer] Logger.Print("Текущая команда этого игрока определена") Infiltrators = CurrentTeam set PlayerVisibilitySeconds[TeamPlayer] = 0.0 Logger.Print("Игрок добавлен в PlayerVisibilitySeconds") then: spawn{OnInfiltratorDamaged(TeamPlayer)} Logger.Print("Игрок появился в качестве захватчика, делаем его невидимым") FortCharacter.Hide() else: Logger.Print("Этот игрок не захватчик")
- Присвойте массиву
Вызов диспетчера невидимости в игре «Меж двух огней»
- Вернитесь в
triad_infiltration_game
и добавьте редактируемое полеinvisibility_manager
в определении класса. Так вы создадите устройство на уровне, которое будет вызывать устройствоtriad_infiltration_game
.# Ссылка на сценарий invisibility_manager, управляющий невидимостью захватчиков. @editable InvisibilityManager:invisibility_manager = invisibility_manager{}
- В функции
OnBegin()
после вызоваBalanceTeams()
вызовитеStartInvisibilityManager()
, передавTeams
,AllPlayers
иInfiltrators
. Ваша функцияOnBegin()
должна выглядеть следующим образом:OnBegin<override>()<suspends>:void = # Получить все команды set Teams = GetPlayspace().GetTeamCollection().GetTeams() # Сохранить команды для последующего обращения set MaybeInfiltrators = option{Teams[0]} set MaybeAttackers = option{Teams[1]} set MaybeDefenders = option{Teams[2]} if: Infiltrators := MaybeInfiltrators? Attackers := MaybeAttackers? Defenders := MaybeDefenders? Logger.Print("Найдены все три команды") set TeamsAndTotals[Infiltrators] = MaximumInfiltrators set TeamsAndTotals[Attackers] = MaximumAttackers set TeamsAndTotals[Defenders] = MaximumDefenders Logger.Print("Все три команды заданы в TeamsAndTotals") then: # Подпишемся на PlayerAddedEvent для возможного перераспределения игроков по командам при присоединении нового игрока GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded) for(PlayerSpawner:PlayersSpawners): PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn) BalanceTeams() Logger.Print("Игроки распределены по командам, вызываем сценарий установки невидимости") InvisibilityManager.StartInvisibilityManager(Teams,AllPlayers, Infiltrators) TeleportPlayersToStartLocations() else: Logger.Print("Не удаётся найти все команды. Убедитесь, что вы задали правильные команды в настройках острова.")
- Сохраните файлы и скомпилируйте их. Выберите устройство на панели Структура и включите все точки появления захватчиков в массив PlayerSpawners.
- Выберите устройство triad_infiltration_game на панели Структура и назначьте устройство invisibility_manager в свойстве InvisibilityManager.
- Нажмите Запустить сеанс на панели инструментов UEFN, чтобы выполнить игровой тест уровня.
Во время игрового теста уровня каждый игрок должен попасть в команду с наибольшей разницей и появиться с оружием, соответствующим его команде. Каждый захватчик должен быть невидимым как в начале игры, так и в момент возрождения.

Что дальше
Дальше вы узнаете, как сделать так, чтобы персонаж захватчика мерцал при получении урона.