Den Algorithmus herausfinden
Wenn das Spiel beginnt, wollen wir dafür sorgen, dass jedes Team eine angemessene Anzahl von Spielern hat.
Im Gegensatz zu Spielen, bei denen die Spielerverteilung symmetrisch ist und die Spieler gleichmäßig auf die Teams verteilt werden, bedeutet eine asymmetrische Verteilung der Teams, dass jedes Team eine relative Anzahl von Spielern haben sollte. Mit anderen Worten: Die Teamgrößen sollten einem relativen Verhältnis folgen.
So kann es zum Beispiel sein, dass ein Team immer doppelt so viele Spieler hat wie ein anderes. Wenn Spieler hinzukommen, musst du sie so ausbalancieren, dass diese relative Anzahl erhalten bleibt. In Spielmodi, in denen ein Team stärker ist oder über andere Fähigkeiten verfügt als das andere Team, sorgt das asymmetrische Balancing für ein reibungsloseres Spielerlebnis, indem es die Anzahl der Spieler in jedem Team sorgfältig verteilt.
In diesem Beispiel musst du sicherstellen, dass Teams mit einer höheren maximalen Spielerzahl (in diesem Fall die Verteidiger) immer mehr Spieler haben als Teams mit einer niedrigeren Maximalzahl (wie die Infiltratoren).
Um die Spieler richtig zu verteilen, musst du jeden Spieler in das Team mit der größten Abweichung von der maximalen Spielerzahl einsetzen.
Dazu musst du für jeden neuen Spieler jedes Team überprüfen und eine Referenz auf die maximale und die aktuelle Anzahl der Spieler in diesem Team sowie auf das Team, dem dieser Spieler zugewiesen werden soll, speichern. Du kannst die maximale Anzahl der Spieler von der aktuellen Anzahl abziehen, um die Differenz zur maximalen Anzahl zu erhalten. Wenn du ein Team mit einer größeren Differenz zum Maximum findest, kannst du den Spieler diesem Team zuordnen.
Indem du die einzelnen Teams iterativ durchgehst, stellst du sicher, dass du das Team mit der größten Differenz findest.
Definition des Algorithmus
In diesem Schritt wird gezeigt, wie man zu Beginn eines Spiels eine asymmetrische Teamaufstellung erreicht.
- Füge eine neue Methode namens
BalanceTeams()zur Klassetriad_infiltration_gamehinzu. Bei dieser Methode wird ein Spieler dem Team zugewiesen, das die größte Differenz zu seiner maximalen Spielerzahl aufweist.# Gleicht alle Spieler in allen Teams im Spiel aus. BalanceTeams():void= Logger.Print("Teams werden ausgeglichen") - Holt alle Spieler im Spiel und speichert sie in dem variablen Array
AllPlayers. Mische dannAllPlayers. Dadurch wird sichergestellt, dass die Spieler nach dem Zufallsprinzip den Teams zugewiesen werden, und nicht nach der Reihenfolge, in der sie dem Spiel beigetreten sind.# Gleicht alle Spieler in allen Teams im Spiel aus. BalanceTeams():void= Logger.Print("Teams werden ausgeglichen") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers) - Nun sollen alle Spieler durchlaufen werden und dem Team mit der größten Differenz zur maximalen Spielerzahl zugeordnet werden. Dies geschieht über eine Hilfsfunktion namens
FindTeamWithLargestDifference(), die du im nächsten Schritt erstellen wirst. Initialisiere jedoch zunächst eine Optionsvariable namensTeamToAssign, um einen Spieler zuzuordnen, und setze sie auf den vonFindTeamWithLargestDifference()zurückgegebenen Wert.for(TeamPlayer:AllPlayers): var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() - Erstelle die Funktion
FindTeamWithLargestDifference()in der Klassendefinitiontriad_infiltration_game. Diese Funktion findet die Mannschaft mit der größten Differenz in der Anzahl der Spieler zum Maximum und gibt ein optionalesteamzurück. Das zurückgegebeneteamsoll eine Option sein, die verhindert, dass ein Spieler neu zugewiesen wird, wenn er bereits in dem Team mit der größten Differenz ist.# Findet das Team mit der größten Differenz zwischen der Anzahl der Spieler # und der maximalen Anzahl an Spielern. FindTeamWithLargestDifference():?team = Logger.Print("Suche nach dem kleinsten Team") - Initialisiere eine optionale Teamvariable mit dem Namen
TeamToAssign, die einen Verweis auf das Team mit dem größten Spielerunterschied und eine GanzzahlLargestDifferencespeichert, um diese Differenz in Spielern zu verfolgen.# Findet das Team mit der größten Differenz zwischen der Anzahl der Spieler # maximale Spieleranzahl. FindTeamWithLargestDifference():?team = Logger.Print("Suche nach dem kleinsten Team") var TeamToAssign:?team = false var LargestDifference:int = 0 - Gehe nun die Liste der Teams durch und ermittle sowohl die aktuelle als auch die maximale Größe des jeweiligen Teams.
var TeamToAssign:?team = false var LargestDifference:int = 0 for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] - Berechne für jedes Team die
DifferenceFromMaximum, d.h. die Differenz zwischen der maximalen Größe dieses Teams und der Anzahl der Spieler, die es derzeit hat. Wenn das Team eine größere Differenz alsLargestDifferenceaufweist, setzeLargestDifferenceaufDifferenceFromMaximum, und verpackeTeamToAssignin eineoption.for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] do: Logger.Print("Team wird überprüft...") Logger.Print("Maximalgröße dieses Teams ist {MaximumTeamSize}") DifferenceFromMaximum := MaximumTeamSize - CurrentTeamSize Logger.Print("Differenz zur Maximalgröße ist {DifferenceFromMaximum}") if(LargestDifference < DifferenceFromMaximum): set LargestDifference = DifferenceFromMaximum set TeamToAssign = option{CandidateTeam} Logger.Print("Team mit weniger als der Maximalanzahl von Spielern gefunden: {DifferenceFromMaximum}") - Gib abschließend
TeamToAssignzurück. DeinFindTeamWithLargestDifference()Code sollte nun wie folgt aussehen:# Findet das Team mit der größten Differenz zwischen der Anzahl der Spieler # maximale Spieleranzahl. FindTeamWithLargestDifference():?team = Logger.Print("Suche nach dem kleinsten Team") var TeamToAssign:?team = false var LargestDifference:int = 0 for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] do: Logger.Print("Team wird überprüft...") Logger.Print("Maximalgröße des Teams {CandidateTeamIndex + 1} ist {MaximumTeamSize}") DifferenceFromMaximum := MaximumTeamSize - CurrentTeamSize Logger.Print("Differenz from Maximum ist {DifferenceFromMaximum}") if(LargestDifference < DifferenceFromMaximum): set LargestDifference = DifferenceFromMaximum set TeamToAssign = option{CandidateTeam} Logger.Print("Team mit weniger als der Maximalanzahl von Spielern gefunden: {DifferenceFromMaximum}") return TeamToAssign - Zurück in
BalanceTeams(), weise den Spieler mit der FunktionFortTeamCollection.AddToTeam[]einem neuen Team zu. Gelingt diese Zuordnung nicht, war der Spieler bereits in der kleinsten Mannschaft.var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, FortTeamCollection.AddToTeam[TeamPlayer, AssignedTeam]): Logger.Print("Versuch, Spieler einem neuen Team zuzuweisen") - Deine Funktion
BalanceTeams()sollte wie folgt aussehen:# Gleicht alle Spieler in allen Teams im Spiel aus. BalanceTeams():void= Logger.Print("Teams werden ausgeglichen") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers) Logger.Print("Länge von AllPlayers ist {AllPlayers.Length}") for(TeamPlayer:AllPlayers): var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, FortTeamCollection.AddToTeam[TeamPlayer, AssignedTeam]): Logger.Print("Spieler wurde neuem Team zugewiesen")
Teleportieren von Spielern in ihren Spawnbereich
Auch wenn die Spieler in dem Team mit der größten Differenz landen, kann es sein, dass sie nicht im richtigen Gebiet spawnen. Das liegt daran, dass Spieler spawnen, bevor sie in einem neuen Team ausgeglichen sind. Um dies zu bewerkstelligen, wirst du eine neue Funktion erstellen, um Spieler zu ihrem Spawn zu teleportieren, nachdem die Teams ausgeglichen sind.
- Erstelle die Funktion
TeleportPlayersToStartLocations()in der Klassendefinitiontriad_infiltration_game. Diese Funktion teleportiert die Spieler zum Spawn ihres Teams, nachdem das Balancing abgeschlossen ist.# Teleportiert Spieler zum Spawnpunkt ihres Teams, nachdem das Team-Balancing abgeschlossen ist. TeleportPlayersToStartLocations():void= Logger.Print("Spieler werden an Startpositionen teleportiert") - In einer
for-Schleife wird jedes Team imTeams-Array durchlaufen, der Index für dieses Team ermittelt und in einer VariablenTeamIndexgespeichert.# Teleportiert Spieler zum Spawnpunkt ihres Teams, nachdem das Team-Balancing abgeschlossen ist. TeleportPlayersToStartLocations():void= Logger.Print("Spieler werden an Startpositionen teleportiert") for: TeamIndex -> PlayerTeam:Teams - Hole die Spieler im
PlayerTeamdurch Aufruf vonGetAgents[]mitPlayerTeam. Anschließend hole den Teleporter, der mit diesem Team verbunden ist, indem du mitTeamIndexin das ArrayTeleportersindizierst und es in einer VariablenTeamTeleporterspeicherst. Speichere die Transformation dieses Teleporters in einer VariablenTransform.# Teleportiert Spieler zum Spawnpunkt ihres Teams, nachdem das Team-Balancing abgeschlossen ist. TeleportPlayersToStartLocations():void= Logger.Print("Spieler werden an Startpositionen teleportiert") for: TeamIndex -> PlayerTeam:Teams TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform()Vergewissere dich, dass die Reihenfolge deiner Teams in
Teamsmit der Reihenfolge deiner Teleporter inTeleportersübereinstimmt. Wenn die Infiltratoren Team 1 sind, dann sollte der erste Teleporter inTeleportersfür die Infiltratoren sein. Überprüfe im Editor, ob diese Werte korrekt sind. - In einer zweiten
for-Schleife wird nun jeder Spieler inTeamPlayersdurchlaufen und mitRespawn()und den Translations- und Rotationswerten vonTransforman der Transformation des Teleporters neu gestartet. Deine FunktionTeleportPlayersToStartLocations()sollte wie folgt aussehen:# Teleportiert Spieler zum Spawnpunkt ihres Teams, nachdem das Team-Balancing abgeschlossen ist. TeleportPlayersToStartLocations():void= Logger.Print("Spieler werden an Startpositionen teleportiert") for: TeamIndex -> PlayerTeam:Teams TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform() do: for(TeamPlayer:TeamPlayers): TeamPlayer.Respawn(Transform.Translation, Transform.Rotation) Logger.Print("Dieser Spieler wurde an seine Startposition teleportiert") - Füge in
OnBegin()einen Aufruf vonBalanceTeams()nach dem Mischen vonAllPlayershinzu. Dadurch wird sichergestellt, dass die Spieler in einer zufälligen Reihenfolge ausbalanciert werden und nicht jedes Mal im selben Team landen. Dann teleportiere die Spieler zu ihren Startorten, indem duTeleportPlayersToStartLocations()aufrufst.OnBegin<override>()<suspends> : void = # Ruft alle Teams ab set Teams = GetPlayspace().GetTeamCollection().GetTeams() # Speichert die Teams, um sie später zu referenzieren set MaybeInfiltrators = option{Teams[0]} set MaybeAttackers = option{Teams[1]} set MaybeDefenders = option{Teams[2]} if: Infiltrators := MaybeInfiltrators? Angreifer:= MaybeAttackers? Defenders := MaybeDefenders? Logger.Print("Alle drei Teams wurden gefunden") set TeamsAndTotals[Infiltrators] = MaximumInfiltrators set TeamsAndTotals[Attackers] = MaximumAttackers set TeamsAndTotals[Defenders] = MaximumDefenders Logger.Print("Setze alle drei Teams in TeamsAndTotals") then: BalanceTeams() TeleportPlayersToStartLocations() else: Logger.Print("Es konnten nicht alle Teams gefunden werden, stelle sicher, dass du die richtigen Teams in deinen Inseleinstellungen zugewiesen hast.") -
Speichere das Script in Visual Studio Code, kompiliere es und klicke in der UEFN-Werkzeugleiste auf "Sitzung starten", um das Level zu testen. Wenn ihr euren Level testet, sollte jeder Spieler in dem Team mit der größten Differenz landen und im Spawn-Bereich dieses Teams spawnen. Überprüfe dieses Verhalten anhand des Logs. Du kannst die maximale Anzahl der Spieler pro Team in deinem
triad_infiltration_gameanpassen, um diese Funktionalität zu testen, wenn du weniger als deine maximale Anzahl von Spielern hast. Testest du zum Beispiel alleine, solltest du die maximale Anzahl der Spieler in dem Team, in dem du landen willst, höher ansetzen als in den anderen beiden Teams. Wenn du auf der Seite der Angreifer landen willst, setzeMaximumAttackershöher. Wenn du bei den Infiltratoren landen willst, setzeMaximumInfiltratorshöher.
Nächster Schritt
Im nächsten Schritt dieses Tutorials lernst du, wie du Spielern zu Beginn des Spiels und beim Spawnen Waffen gewähren kannst.