Of the three teams, the Infiltrators will play the most unique role in your game. The Infiltrators are stealthy, and start the game invisible. They spawn with a high-damage, bolt-action rifle, and can score eliminations from the shadows as they sneak their way toward the Defender's base. The Infiltrators are not always invisible, however, as getting hit will mean they temporarily lose their invisibility, flickering in and out of sight.
In this tutorial, you'll also learn how to make every Infiltrator on a team flicker when one of them is damaged, or to keep the individual flickering. Flickering as a team creates a more difficult experience for the Infiltrators, but encourages more careful play.
Follow these steps to learn how to turn Infiltrators invisible when they spawn.
Creating the Invisibility Manager
Create a new Verse device named invisibility_manager using Verse Explorer, and drag the device into the level.
At the top of the
invisibility_managerfile, addusing { /Fortnite.com/Characters }to get thefort_characterassociated with a player.using { /Fortnite.com/Devices } using { /Fortnite.com/Characters } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics }In the
invisibility_managerclass definition, add the following fields:An editable array of player spawners
PlayerSpawners. This will track the player spawners for the Infiltrators and will be used to make them invisible when they spawninvisibility_manager := class(creative_device): Logger:log = log{Channel := triad_invisibility_log_channel} # Array of players spawners for the Infiltrators team @editable PlayersSpawners:[]player_spawner_device = array{}An editable logic
IsVisibilityShared. This will determine if flickering after being damaged happens for all Infiltrators at the same time or only for the player that was damaged.# Array of players spawners for the Infiltrators team @editable PlayersSpawners:[]player_spawner_device = array{} # Whether the visibility of the infiltrators is shared with teammates. @editable IsVisibilityShared:logic = trueAn editable float
VulnerableSecondsand an editable floatFlickerRateSeconds. The first one controls how long Infiltrators flicker after being damaged, and the second controls how fast the flickering animation plays.# Whether the visibility of the infiltrators is shared with teammates. @editable IsVisibilityShared:logic = true # How long the infiltrators are visible for after being damaged. @editable VulnerableSeconds:float = 3.0 # How quickly infiltrators flicker after being damaged. @editable FlickerRateSeconds:float = 0.4A variable team array named
Teams. You'll use this to check whether a player is an Infiltrator.# How quickly infiltrators flicker after being damaged. @editable FlickerRateSeconds:float = 0.4 # Array of all teams in the game. var Teams:[]team = array{}A variable map of
agenttofloatnamedPlayerVisibilitySeconds. This maps individual agents to the number of seconds of flickering they have left after being damaged.var Teams:[]team = array{} # Array of all teams in the game. var Teams:[]team = array{} # Map of players to the amount of seconds they have left to keep blinking. var PlayerVisibilitySeconds:[agent]float = map{}
In
OnBegin(), add a simple log statement to verify that the device has started. You want to make sure thatinvisibility_managerruns after teams have been balanced by thetriad_infiltration_gamescript to prevent players on the wrong team from ending up with invisibility. To guarantee this, you'll startinvisibility_managerfromtriad_infiltration_game, rather than having code run inOnBegin().OnBegin<override>()<suspends>:void= # Wait for teams to be balanced before subscribing to events that make the players invisible. Logger.Print("Waiting for teams to be balanced...")Add a new method
OnPlayerSpawn()to theinvisibility_managerclass definition. You want to make sure the Infiltrators are invisible whenever they spawn, so you'll handle this function first.Verse# Handles a player spawning from an infiltrator spawn pad OnPlayerSpawn(SpawnedAgent:agent):void= Logger.Print("A player just spawned from an infiltrator spawn pad!")In
OnPlayerSpawn(), get thefort_characterassociated with the spawned agent usingGetFortCharacter[]and save it in a variableFortCharacter. Also, get the team of the spawned agent usingGetTeam[]and save it in a variableCurrentTeam.Verse# Handles a player spawning from an infiltrator spawn pad OnPlayerSpawn(SpawnedAgent:agent):void= Logger.Print("A player just spawned from an infiltrator spawn pad!") if: FortCharacter:fort_character = SpawnedAgent.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[SpawnedAgent]Check if
CurrentTeammatches the first team in theTeamsarray, which should be the Infiltrators. If so, this agent is an Infiltrator, and you can callHide()on the agent'sFortCharacter. This will make the agent invisible when they spawn. YourOnPlayerSpawn()function should look like:Verse# Handles a player spawning from an infiltrator spawn pad OnPlayerSpawn(SpawnedAgent:agent):void= Logger.Print("A player just spawned from an infiltrator spawn pad!") if: FortCharacter:fort_character = SpawnedAgent.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[SpawnedAgent] Teams[0] = CurrentTeam Logger.Print("Player spawned as an infiltrator, making them invisible") then: FortCharacter.Hide()
Add a new method
StartInvisibilityManager()to theinvisibility_managerclass definition. This function takes an array of type teamAllTeams, an array of type playerAllPlayers, and a reference to the Infiltrators team of typeteam. You'll call this fromtriad_infiltration_gameto start theinvisibility_managerlogic, so this function must have the<public>specifier to allowtriad_infiltration_gameto find it.# Starts the invisibility manager logic. Called from triad_infiltration class after team balancing finishes StartInvisibilityManager<public>(AllTeams:[]team, AllPlayers:[]player, Infiltrators:team):void= Logger.Print("Invisibility script started!")In
StartInvisibilityManager():Set the
Teamsarray to theAllTeamsarray.# Starts the invisibility manager logic. Called from triad_infiltration class after team balancing finishes StartInvisibilityManager<public>(AllTeams:[]team, Players:[]player, Infiltrators:team):void= Logger.Print("Invisibility script started!") set Teams = AllTeamsIn a
forloop, subscribe each player spawner inPlayerSpawnersto yourOnPlayerSpawn()function.for(PlayerSpawner:PlayersSpawners): PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn)When the script starts, you want to find each Infiltrator and make them invisible. You also want to create an entry for them in your
PlayerVisibilitySecondsmap. You'll use this later to track how long each damaged Infiltrator should flicker for. Just like inOnPlayerSpawn(), get thefort_characterandteamfor each player.Versefor(PlayerSpawner:PlayersSpawners): PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn) # For each player, if they spawned on the infiltrator team, spawn an OnInfiltratorDamaged function for that # player. Then make their character invisible. for(TeamPlayer:AllPlayers): if: FortCharacter:fort_character = TeamPlayer.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]Check if
CurrentTeammatches theInfiltratorsteam you passed to this function. If so, set the player's key inPlayerVisibilitySecondsto0.0.Versefor(TeamPlayer:AllPlayers): if: FortCharacter:fort_character = TeamPlayer.GetFortCharacter[] CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer] Logger.Print("Got this player's current team") Infiltrators = CurrentTeam set PlayerVisibilitySeconds[TeamPlayer] = 0.0 Logger.Print("Added player to PlayerVisibilitySeconds")Finally, make the player invisible by calling
Hide()on the player'sFortCharacter. YourStartInvisibilityManagershould look like the following:Verse# Starts the invisibility manager logic. Called from triad_infiltration class after team balancing finishes StartInvisibilityManager<public>(AllTeams:[]team, Players:[]player, Infiltrators:team):void= Logger.Print("Invisibility script started!") set Teams = AllTeams for(PlayerSpawner:PlayersSpawners): PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn) # For each player, if they spawned on the infiltrator team, spawn an OnInfiltratorDamaged function for that # player. Then make their character invisible. for(TeamPlayer:AllPlayers):
Calling Invisibility Manager from Triad Infiltration Game
Back in
triad_infiltration_game, add an editableinvisibility_managerto the class definition. This will be the device in your level that yourtriad_infiltration_gamedevice calls.# Reference to the invisibility_manager script that controls infiltrator invisibility. @editable InvisibilityManager:invisibility_manager = invisibility_manager{}In the
OnBegin()function after the call toBalanceTeams(), callStartInvisibilityManager(), passingTeams,AllPlayers, andInfiltrators. YourOnBegin()function should look like:VerseOnBegin<override>()<suspends>:void = # Get all the Teams set Teams = GetPlayspace().GetTeamCollection().GetTeams() # Save the teams to later reference them set MaybeInfiltrators = option{Teams[0]} set MaybeAttackers = option{Teams[1]} set MaybeDefenders = option{Teams[2]} if: Infiltrators := MaybeInfiltrators?Save the files and compile them. Select the device in the Outliner, and assign any spawn pads for the Infiltrators to the PlayerSpawners array.
Select your triad_infiltration_game device in the Outliner, and assign your invisibility_manager device to its InvisibilityManager property.
Click Launch Session in the UEFN toolbar to playtest the level.
When you playtest your level, each player should end up on the team with the largest difference and should spawn with an appropriate weapon for their team. Each Infiltrator should be invisible, both when the game starts and when they respawn.
Next Step
In the next step of this tutorial, you'll learn how to flicker an Infiltrator's character when they're damaged.