When a new player joins the game, they need to be balanced asymmetrically onto the right team. If that team happens to be the Infiltrators, they also need to have an instance of OnInfiltratorDamaged() associated with them.
Follow the steps below to learn how to balance players to the correct team when they join the game in progress.
Setting Up Player Join Functions
Add a new function,
OnInfiltratorJoined(), to theinvisibility_managerclass definition. This function takes an agent and spawns an instance ofOnInfiltratorDamaged()with the given agent. Add the ` <public> ` specifier to this function, since you'll be calling it fromtriad_infiltration_game.# Spawns an OnInfiltratorDamaged function when a new infiltrator joins the game OnInfiltratorJoined<public>(InAgent:agent):void= spawn{OnInfiltratorDamaged(InAgent)}Add a new function
OnPlayerAdded()to thetriad_infiltration_gameclass definition. This function takes a player, balances them to the correct team, and callsOnInfiltratorJoined()if the new player is an Infiltrator.# Handles a new player joining the game. OnPlayerAdded(InPlayer:player):void=Get the
fort_team_collectionfor the current playspace and save it in a variableFortTeamCollection.# Handles a new player joining the game. OnPlayerAdded(InPlayer:player):void= Logger.Print("A new Player joined, assigning them to a team") FortTeamCollection := GetPlayspace().GetTeamCollection()Refactoring Team BalancingYou need to balance the new player onto the correct team, but if you call
BalanceTeams()you'll end up rearranging every player onto a new team. Instead of rewriting the code for finding the smallest team for the new player and balancing them onto it, this is a good opportunity for refactoring.Add a new method
BalancePlayer()to thetriad_infiltration_gameclass definition. This method takes a player and balances them asymmetrically onto the correct team.# For each player, iterate through the list of teams and assign them to the # team with the least amount of players, or their starting team in case of ties. BalancePlayer(InPlayer:player):void= Logger.Print("Beginning to balance player")Extract the code inside the
forloop inBalanceTeams()and place it insideBalancePlayer(), renamingTeamPlayertoInPlayer. YourBalancePlayer()code should look like the following:Verse# For each player, iterate through the list of teams and assign them to the # team with the least amount of players, or their starting team in case of ties. BalancePlayer(InPlayer:player):void= Logger.Print("Beginning to balance player") var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, GetPlayspace().GetTeamCollection().AddToTeam[InPlayer, AssignedTeam]): Logger.Print("Attempting to assign newly joined to a new team") else: Logger.Print("This player was already on the smallest team")Now in
BalanceTeams(), add a call toBalancePlayer()inside theforloop. This preserves the functionality ofBalanceTeams()while also allowing you to balance a player individually. YourBalanceTeams()code should look like:# Balances all players on all teams in the game BalanceTeams():void= Logger.Print("Beginning to balance teams") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers) Logger.Print("AllPlayers Length is {AllPlayers.Length}") for (TeamPlayer : AllPlayers): BalancePlayer(TeamPlayer)
Back in
OnPlayerAdded(), add a call toBalancePlayer()passing the player who just joined.# Handles a new player joining the game. OnPlayerAdded(InPlayer:player):void= Logger.Print("A new Player joined, assigning them to a team") FortTeamCollection := GetPlayspace().GetTeamCollection() set AllPlayers = GetPlayspace().GetPlayers() # Assign the new player to the smallest team BalancePlayer(InPlayer)Find the index of player's team after balancing by iterating through each team in the
Teamsarray, usingGetTeam[]as a filter to check that it equalsPlayerTeam.Verse# Handles a new player joining the game. OnPlayerAdded(InPlayer:player):void= Logger.Print("A new Player joined, assigning them to a team") FortTeamCollection := GetPlayspace().GetTeamCollection() # Assign the new player to the smallest team, asymmetrically. BalancePlayer(InPlayer) for: TeamIndex -> PlayerTeam:TeamsGet the teleporter associated with the player's team by indexing into the
Teleportersarray usingTeamIndexand storing it in a variableTeamTeleporter. Store the transform of that teleporter in a variableTransform. Then respawn the new player at their team's starting teleporter.Versefor: TeamIndex -> PlayerTeam:Teams PlayerTeam = FortTeamCollection.GetTeam[InPlayer] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform() do: InPlayer.Respawn(Transform.Translation, Transform.Rotation) Logger.Print("Teleported the spawned player to their start location")Finally, check if the player who just joined is an Infiltrator by comparing their team against the
Infiltratorsoption you set up earlier. If they are, callOnInfiltratorJoined()from theinvisibility_managerclass on the new player to allow them to start flickering. YourOnPlayerAdded()code should look like:Verse# Handles a new player joining the game. OnPlayerAdded(InPlayer:player):void= Logger.Print("A new Player joined, assigning them to a team") FortTeamCollection := GetPlayspace().GetTeamCollection() # Assign the new player to the smallest team, asymmetrically. BalancePlayer(InPlayer) for: TeamIndex -> PlayerTeam:TeamsSave the script, build it, and click Launch Session in the UEFN toolbar to playtest the level. When you playtest your level, players should join the correct team when they join a game in progress. If that player is an Infiltrator, they should spawn invisible and flicker on taking damage.
Next Step
In the next step of this tutorial, you'll learn how to create a visual indicator for a player when they capture an objective.