Dieses Tutorial baut auf den Konzepten in Dauerhafte Spielerstatistiken auf, also sieh dir das zuerst an!
Ranglisten sind ein wesentlicher Bestandteil von Wettkampfspielen. Sie bieten den Spielern die Möglichkeit, ihre Fertigkeiten unter Beweis zu stellen und sich einen Namen zu machen. Sie vermitteln den Spielern ein Gefühl für den Fortschritt und ermutigen sie, immer wieder zurückzukommen, um sich selbst an die Spitze zu bringen.
Verse-Persistenz stellt das Werkzeug zur Verfügung, mit dem du diese Ranglisten erstellen und deinem Erlebnis einen Wettbewerbsvorteil verschaffen kannst. Im Tutorial zu dauerhaften Spielerstatistiken hast du bereits gesehen, wie du dauerhafte Daten zwischen den Spielsitzungen verfolgen kannst und wie du diese Daten auf der Grundlage verschiedener Events ändern und aktualisieren kannst. Jetzt wendest du dieses Wissen an, um zu lernen, wie du vollständige lokale Bestenlisten erstellst, Spieler-Statistiken sortierst und alles in einem Rennspiel zusammenfügst!
Verwendete Sprachfunktionen in Verse
Klasse: Dieses Beispiel erstellt eine dauerhafte Verse-Klasse, die eine Gruppe von Statistiken für einen einzelnen Spieler verfolgt.
Constructor: Ein Constructor ist eine spezielle Funktion, die eine Instanz der Klasse erzeugt, mit der sie assoziiert ist.
weak_map: Eine weak_map ist eine einfache Map, über die nicht iteriert werden kann. Dauerhafte Verse-Daten müssen in einer weak_map gespeichert werden.
Level einrichten
Dieses Beispiel verwendet die folgenden Objekte und Geräte:
3 x Reklametafel-Gerät: Diese zeigen die Lebenszeit-Statistiken jedes Spielers an, und Sie können sie nach Lebenszeit-Punkten sortieren, um die besten Spieler in der Lobby zu präsentieren.
3 x Spieler-Referenzgerät: In Kombination mit den Reklametafeln geben die Spieler-Referenzen den Namen Ihrer Top-Performer ein Gesicht, damit andere Spieler wissen, auf wen sie während des Spiels achten müssen.
3 x Checkpoint-Gerät: Dies sind die Checkpoints, die die Spieler passieren müssen, um das Rennen zu beenden.
1 x Rennmanager-Gerät: Dieses verfolgt, wann die Spieler das Rennen beginnen und beenden, und vergibt ihnen Punkte basierend auf ihrer Platzierung im Ziel.
1 x Spawner-Gerät für Pickup-Trucks: Damit wird das Fahrzeug gespawnt, das du während des Rennens verwendest. Du kannst es jedoch je nach Erfahrung auf jedes beliebige Fahrzeug ändern.
Folge diesen Schritten, um dein Level einzurichten:
Reklametafeln und Spielerreferenzen
Um die Spieler-Statistiken anzuzeigen, verwendest du eine Kombination aus Reklametafeln und Spielerreferenzen. Auf jeder Reklametafel werden die Lebensstatistiken eines Spielers angezeigt, während die Spielerreferenz eine visuelle Darstellung des Spielers zeigt. Folge diese Anweisungen, um diese Elemente hinzuzufügen:
Füge deinem Level drei Spielerreferenz-Geräte hinzu und platziere sie nebeneinander.
Wähle für jede Spielerreferenz diese im Outliner aus. Lege im Details-Panel unter Benutzeroptionen die Farbe Benutzerdefinierte Farbe auf die Farbe fest, die den ersten, zweiten und dritten Spieler mit der besten Leistung in der Lobby darstellen soll. In diesem Beispiel werden die Farben Gold, Silber und Bronze verwendet.
Füge deinem Level drei Reklametafel-Geräte hinzu und platziere eines vor jeder Spielerreferenz. Du aktualisierst diese zu Spielbeginn mithilfe von Verse mit den Statistiken der einzelnen Spieler.
Checkpoints, Pickup-Truck und Rennmanager
Da es sich um ein Rennen handelt, brauchst du etwas, womit du Rennen fahren kannst! Du benötigst außerdem Checkpoints, die du passieren kannst, und einen Rennmanager, der das Rennen während des Spiels leitet. Folge diese Anweisungen, um diese Elemente hinzuzufügen:
Füge deinem Level drei Renn-Checkpoint-Geräte hinzu. Platziere sie in der Reihenfolge, in der die Spieler sie durchlaufen sollen. Stelle für jeden Checkpoint im Outliner sicher, dass die Checkpoint-Nummer mit der Reihenfolge übereinstimmt, in der die Spieler die Checkpoints durchlaufen.
Füge deinem Level ein Rennmanager-Gerät hinzu. Dieser kümmert sich um die Durchführung des Rennens und die Leitung der Spieler zu den Checkpoints. Du hörst auf das
RaceCompletedEvent()von diesem Gerät später, um herauszufinden, wenn ein Spieler das Rennen beendet.Füge deinem Level ein Pickup-Truck-Spawner-Gerät hinzu. Ein Fahrzeug ist optional, aber in dieser Anleitung wird ein Pickup-Truck verwendet, der zur Speedway-Vorlage passt und den Spielern etwas zum Herumfahren gibt.
Anpassen deiner Statistiktabelle
In diesem Beispiel wird eine geänderte Version der Datei player_stats_table aus Dauerhafte Spielerstatistiken verwendet. Diese sieht ähnlich aus wie die Datei aus diesem Beispiel, weist jedoch einige wichtige Unterschiede auf, die die Implementierung verändern.
Führe die folgenden Schritte aus, um deine Spieler-Statistiken zu erstellen:
In deiner Klasse
player_stats_table:Entferne die Statistik
Losses.Ändere die Statistik
ScorezuPoints.Verse# Tracks different persistable stats for each player. player_stats_table<public>:= class<final><persistable>: # The version of the current stats table. Version<public>:int = 0 # The Points of a player. Points<public>:int = 0 # The number of Wins for a player.
Modifiziere die Constructor-Funktion
MakePlayerStatsTable()in deiner Datei, um die aktualisierten Statistiken zu reflektieren.Verse# Creates a new player_stats_table with the same values as the previous player_stats_table. MakePlayerStatsTable<constructor>(OldTable:player_stats_table)<transacts> := player_stats_table: Version := OldTable.Version Points := OldTable.Points Wins := OldTable.WinsFüge die neue Struktur
player_stats_table.versezu deiner Datei player_stats_table.verse hinzu. Diese Struktur enthält eine Referenz auf einenplayerund seineplayer_stats_table-Klasse, damit man beide Daten in Funktionen verwenden kann, ohne sie wiederholt abrufen zu müssen. Deine fertige Strukturplayer_and_statssollte wie folgt aussehen:Verse# Structure for passing a player and their stats as arguments. player_and_stats<public> := struct: Player<public>:player StatsTable<public>:player_stats_table
Verwalten von Statistiken
Wie in Dauerhafte Spielerstatistiken verwendest du eine Managerdatei zum Verwalten und Aufzeichnen von Statistikänderungen für Spieler.
Folge den nachfolgenden Schritten, um deine modifizierte player_stats_manager-Datei zu erstellen.
Ändere die Funktionssignatur von
InitializeAllPlayers()undInitializePlayer()inInitializeAllPlayerStats()undInitializePlayerStat(). Diese Namen spiegeln ihre Beziehung zur FunktionGetPlayerStat()besser wieder. Deine aktualisierte Funktion sollte wie folgt aussehen:Verse# Initialize stats for all current players. InitializeAllPlayerStats<public>(Players:[]player):void = for (Player : Players): InitializePlayerStat(Player) # Initialize stats for the given player. InitializePlayerStat<public>(Player:player):void= if: not PlayerStatsMap[Player] set PlayerStatsMap[Player] = player_stats_table{}Ändere die Funktionssignatur von
AddScore()inAddPoints(). Entferne dann die FunktionAddLosses(), da deineplayer_stats_tablediesen Wert nicht mehr enthält. Deine fertige Dateiplayer_stats_managersollte wie folgt aussehen:Verse# This file handles the code for initializing, updating, and returning player_stats_tables # for each player. It also defines an abstract stat_type class to use for updating stats, and the # StatType module to use when displaying stats. using { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Return the player_stats_table for the provided Agent. GetPlayerStats<public>(Agent:agent)<decides><transacts>:player_stats_table=
Erstellen von Spieler-Ranglisten
Um Spielerdaten in deinen Ranglisten anzuzeigen, benötigst du einige Dinge. Du benötigst eine Möglichkeit, den Text auf den Reklametafeln und die Spieler auf den Spielerreferenz-Geräten zu aktualisieren. Du benötigst außerdem eine Möglichkeit, diese Geräte zu sortieren, da die Top-Spieler in deiner Rangliste ganz oben stehen sollen. Da diese Funktionen das gleiche Ziel haben, nämlich Geräte im Level zu ändern, empfiehlt es sich, die Funktionen in einer gemeinsamen Datei zu gruppieren.
Führe die folgenden Schritte aus, um Funktionen zu erstellen, die deine Geräte auf dem Level aktualisieren:
Erstelle eine neue Verse-Datei mit dem Namen player_leaderboards.verse. In dieser Datei werden die üblichen Funktionen zum Aktualisieren deiner Bestenlisten im Level gespeichert.
Für den Text auf der Reklametafel verwendest du eine Nachricht, der du Argumente übergeben kannst. Erstelle eine neue Nachricht namens
StatsMessage, dieCurrentPlayer,PointsundWinsentgegennimmt, alle vom Typmessage, und den kombinierten Text alsmessagezurückgibt.Verse# The message to display on the stats billboard. StatsMessage<localizes>(CurrentPlayer:message, Points:message, Wins:message):message= "{CurrentPlayer}:\n{Points}\n{Wins}"Füge drei weitere
message-Variablen hinzu, eine für jeden der Inputs zuStatsMessage. Die NachrichtPlayerTexterwartet einenAgent, die NachrichtPointsTexterwartet die Punkte dieses Agents und die NachrichtWinsTexterwartet die Siege dieses Agents. DieStatsMessageerstellt eine Nachricht aus alle diesen Daten, um sie sauber in dem Level anzuzeigen.Verse# The message to display on the stats billboard. StatsMessage<localizes>(CurrentPlayer:message, Points:message, Wins:message):message= "{CurrentPlayer}:\n{Points}\n{Wins}" PlayerText<localizes>(CurrentPlayer:agent):message = "Player {CurrentPlayer}" PointsText<localizes>(Points:int):message = "Total Points {Points}" WinsText<localizes>(Wins:int):message = "{Wins} Total Wins"Um eine Reklametafel zu aktualisieren, rufst du die Funktion
UpdateStatsBillboard()aus dem Tutorial „Dauerhafte Spielerstatistiken“ auf. Da diese Funktion in einer anderen Datei als das Verse-Gerät definiert ist, musst duStatsBillboardals zusätzliches Argument hinzufügen, um anzugeben, welche Reklametafel du aktualisieren möchtest.Verse# Updates the given billboard device to display the stats of the given player. UpdateStatsBillboard<public>(Player:agent, StatsBillboard:billboard_device):void=Rufe zuerst die Statistiken des als Argument übergebenen Spielers mit
GetPlayerStats[]ab. Du benötigst keine Referenz auf einenplayer_stats_manager, da es keine separate Klasse mehr ist. Erstelle dann eine neueStatsMessageunter Verwendung des Spielers und derPointsundWinsaus dessenCurrentPlayerStats. Rufe zum SchlussSetText()auf demStatsBillboardauf, um den Text der Reklametafel auf dem Level zu aktualisieren. Deine fertige FunktionUpdateStatsBillboard()sollte wie folgt aussehen:Verse# Updates the given billboard device to display the stats of the given player. UpdateStatsBillboard<public>(Player:agent, StatsBillboard:billboard_device):void= if: CurrentPlayerStats := GetPlayerStats[Player] then: PlayerStatsText := StatsMessage( PlayerText(Player), PointsText(CurrentPlayerStats.Points), WinsText(CurrentPlayerStats.Wins)) StatsBillboard.SetText(PlayerStatsText)
Sortieren und Anzeigen des besten Spielers
Bevor du fortfährst, musst du überlegen, wie du diese Reklametafeln sortieren möchtest. Soll der Spieler mit den meisten Punkten oben stehen oder soll der Spieler mit den meisten Siegen? Was ist, wenn du nach verschiedenen Statistiken sortieren möchtest? Du benötigst eine Methode, um alle diese zu verarbeiten, und ein Sortieralgorithmus ist die Antwort. Mithilfe eines Sortieralgorithmus und einer Vergleichsfunktion kannst du festlegen, nach welchen Kriterien sortiert werden soll. Du kannst dann deine Reklametafeln und Spielerreferenzen sortieren, um die Top-Spieler deines Erlebnisses anzuzeigen. Dieses Beispiel verwendet den Sortieren zusammenführen-Algorithmus, du kannst jedoch auch deinen eigenen implementieren.
Führe die folgenden Schritte aus, um Vergleiche und Sortierungen zu deinen Reklametafeln hinzuzufügen und die Aktualisierung der Geräte in deinem Level abzuschließen.
Zurück in der Datei
player_stats_tabledefinierst du Vergleichsfunktionen für jede deiner Statistiken. Jede nimmt eineLeft- undRight-player_and_stats-Struktur entgegen und vergleicht sie anhand einer bestimmten Statistik. Diese Funktionen haben die Modifikatoren<decides><transacts>. Wenn der Vergleich fehlschlägt, schlägt auch die Funktion fehl. Zum Beispiel, um dir mitzuteilen, dassLeftkleiner alsRightist. Füge eine neue Funktion namensMorePointsComparison()zu deiner player_stats_table.verse-Datei hinzu. Diese Funktion prüft, obLeft.Pointsgrößer alsRight.Pointsist, und schlägt andernfalls fehl. Wenn sie erfolgreich ist, gibt sieLeft‘ zurück.Verse# Returns Left if Left has greater Points than Right. MorePointsComparison<public>(Left:player_and_stats, Right:player_and_stats)<decides><transacts>:Left= Left.StatsTable.Points > Right.StatsTable.Points LeftKopiere diese Funktion dreimal, einmal für den Vergleich weniger Punkte und zweimal für den Vergleich der Siege. Deine Vergleichsfunktionen sollten wie folgt aussehen:
Verse# Returns Left if Left has greater Points than Right. MorePointsComparison<public>(Left:player_and_stats, Right:player_and_stats)<decides><transacts>:player_and_stats= Left.StatsTable.Points > Right.StatsTable.Points Left # Returns Left if Left has less Points than Right. LessPointsComparison<public>(Left:player_and_stats, Right:player_and_stats)<decides><transacts>:player_and_stats= Left.StatsTable.Points < Right.StatsTable.Points LeftFüge den Algorithmus Sortieren zusammenführen hinzu. Du kannst ihn in einer separaten Datei oder einem Modul unterbringen und den Algorithmus an der bereitgestellten Testdatei testen.
Zurück in
player_leaderboards, füge eine neue FunktionUpdateStatsBillboards()hinzu. Diese Funktion nimmt ein Array von Agents und ein Array von Reklametafeln entgegen, sortiert sie und ruftUpdateStatsBillboard()auf, um jede Reklametafel im Level zu aktualisieren.Verse# Update the stats billboards by sorting them based on the amount of lifetime points # each player has. UpdateStatsBillboards<public>(Players:[]agent, StatsBillboards:[]billboard_device):void=Initialisiere in
UpdateStatsBillboards()eine neue Array-Variable vonplayer_and_statsmit dem NamenPlayerAndStatsArray. Setze dies gleich dem Ergebnis einesfor-Ausdrucks. In diesemfor-Ausdruck rufst du für jedenagentdenplayerfür diesenagentab und rufst dessenplayer_stats_tablemitGetPlayerStats[]ab. Gib dann eineplayer_and_stats-Struktur zurück, die aus demplayerund ihrer Statistiken-Tabelle erstellt wurde.VerseUpdateStatsBillboards<public>(Players:[]agent, StatsBillboards:[]billboard_device):void= var PlayerAndStatsArray:[]player_and_stats = for: Agent:Players Player := player[Agent] PlayerStats := GetPlayerStats[Player] do: player_and_stats: Player := Player StatsTable := PlayerStatsUm dein
PlayerAndStatsArrayzu sortieren, initialisiere eine neue VariableSortedPlayersAndStatsmit dem Ergebnis des Aufrufs vonMergeSort()und übergib das Array und denMorePointsComparison. Nach dem Sortieren in einemfor-Ausdruck iterierst du durch jedes Element inSortedPlayerAndStatsund speicherst den Elementindex in einer VariablenPlayerIndex. VerwendePlayerIndex, um in das ArrayStatsBillboardszu indexieren, und rufe dannUpdateStatsBillboardmit dem Spieler und der zu aktualisierenden Reklametafel auf. Deine fertige FunktionUpdateStatsBillboards()sollte wie folgt aussehen:Verse# Update the stats billboards by sorting them based on the amount of lifetime points # each player has. UpdateStatsBillboards<public>(Players:[]agent, StatsBillboards:[]billboard_device):void= var PlayerAndStatsArray:[]player_and_stats = for: Agent:Players Player := player[Agent] PlayerStats := GetPlayerStats[Player] do: player_and_stats:Um deine Spielerreferenzen zu aktualisieren, verwendest du eine sehr ähnliche Funktion namens
UpdatePlayerReferences(). Diese Funktion nimmt ein Array vonplayer_reference_deviceanstelle von Reklametafeln entgegen, und anstatt am EndeUpdateStatsBillboard()aufzurufen, ruftRegister()auf dem Spieler-Referenz-Gerät für jeden Spieler auf. Kopiere deinenUpdateStatsBillboard()-Code in eine neue FunktionUpdatePlayerReferences()mit den oben genannten Änderungen. Deine fertige FunktionUpdatePlayerReferences()sollte wie folgt aussehen:Verse# Update the player references devices by sorting them based on the amount # of lifetime points each player has. UpdatePlayerReferences<public>(Players:[]player, PlayerReferences:[]player_reference_device):void= var PlayerAndStatsArray:[]player_and_stats = for: Agent:Players Player := player[Agent] PlayerStats := GetPlayerStats[Player] do: player_and_stats:
Spieler-Ranglisten in deinem Level
Wenn du alles eingerichtet hast, ist es Zeit, deine Spieler zu präsentieren! Du erstellst ein Gerät, das Punkte an die Spieler vergibt, wenn sie mit der Schaltfläche interagieren, und sortierst die Spielerreferenzen und Reklametafeln so, dass die besten Spieler vorne und in der Mitte stehen. Befolge die folgenden Schritte, um ein Verse-Gerät zu erstellen und Ranglisten in deinem Level zu testen:
Erstelle ein neues Verse-Gerät mit dem Namen player_leaderboards_example. Weitere Schritte findest Du unter Create Your Own Device Using Verse.
Füge oben in der Klassendefinition von
player_leaderboards_example classdie folgenden Felder hinzu:Ein editierbares Array von Spieler-Referenz-Geräten mit dem Namen
PlayerReferences. Diese visualisieren die einzelnen Spieler im Rennen.Verse# Visual representations of each player. @editable PlayerReferences:[]player_reference_device = array{}Ein editierbares Array von Reklametafel-Geräten mit dem Namen
Leaderboards. Diese zeigen die Statistiken jedes Spielers auf einer Reklametafel im Level an.Verse# Billboards that display each player's stats. @editable Leaderboards:[]billboard_device = array{}Ein editierbares Rennmanager-Gerät mit dem Namen
RaceManager. Du abonnierst Events des Rennmanagers, um zu erfahren, wann ein Spieler das Rennen beendet.Verse# Tracks when players complete a race, with the players in the first spot being awarded a win. @editable RaceManager:race_manager_device = race_manager_device{}Eine editierbare Ganzzahl mit dem Namen
PlacementRequiredForWin. Dies ist die Platzierung, die ein Spieler erreichen muss, um als Sieger ausgezeichnet zu werden.Verse# The placement of a player must be at or below to award a win. @editable PlacementRequiredForWin:int = 1Ein editierbares Array von Ganzzahlen mit dem Namen
PointsPerPlace. Dies ist die Anzahl der Punkte, die jeder Spieler aufgrund seiner Platzierung erhält.Verse# The number of points a player in each place earns. # Adjust this to award your players the desired amount of score # based on their placement. @editable PointsPerPlace:[]int = array{5, 3, 1}Eine Ganzzahl-Variable mit dem Namen
CurrentFinishOrder. Dies ist die Platzierung des Spielers, der das Rennen zuletzt abgeschlossen hat.Verse# The spot of the player who just finished the race. # The first three players to finish the race will be awarded a win. var CurrentFinishOrder:int = 0
Vergabe von Statistiken basierend auf der Platzierung
Wenn ein Spieler das Rennen beendet, möchtest du seine Statistiken auf Basis seiner Platzierung aktualisieren. Spieler, die eine gute Platzierung erreichen, sollten eine größere Anzahl von Punkten erhalten, und Spieler, die die besten Platzierungen hatten, sollten einen Sieg erhalten.
Befolge diese Schritte, um den Spielern Statistiken zu geben, wenn sie das Rennen beenden:
Um dies zu handhaben, füge eine neue Funktion
RecordPlayerFinish()zu deiner Klassendefinition vonplayer_leaderboards_examplehinzu. Diese Funktion nimmt den Spieler, der ausgezeichnet werden soll, als Parameter entgegen.Verse# When a player finishes the race, award them points based on their placement, and award them a win if # their placement was better than the PlacementRequiredForWin. RecordPlayerFinish(Player:agent):void=Rufe in
RecordPlayerFinish()die Position dieses Spielers ab, indem du den aktuellen Wert vonCurrentFinishOrderin einem neuenintmit dem NamenPlayerFinishOrderabrufst. Erhöhe dannCurrentFinishOrder, damit der nächste Spieler, der das Spiel beendet, nicht an der gleichen Stelle endet.VerseRecordPlayerFinish(Player:agent):void= PlayerFinishOrder:int = CurrentFinishOrder set CurrentFinishOrder += 1Jetzt ist es an der Zeit, Statistiken zu vergeben. Um zu wissen, wie viele Punkte dieser Spieler erhalten soll, verwende in einem
if-Ausdruck den Index in das ArrayPointsPerPlacemitPlayerFinishOrder. Rufe dannAddPoints()auf, um dem Spieler so viele Punkte zu verleihen.Verseset CurrentFinishOrder += 1 if: PointsToAward := PointsPerPlace[PlayerFinishOrder] then: AddPoints(Player, PointsToAward)Wenn die Platzierung des Spielers hoch genug war, um einen Sieg zu holen, musst du einen Sieg in seiner Statistiktabelle eintragen. Prüfe in einem anderen
if-Ausdruck, obPlayerFinishOrderkleiner war alsPlacementRequiredToWin. Wenn ja, rufeAddWin()auf um den Spieler und einen Gewinn zu übergeben, der ihnen gutgeschrieben werden soll. Deine fertige FunktionRecordPlayerFinish()sollte wie folgt aussehen:Verse# When a player finishes the race, award them points based on their placement, and award them a win if # their placement was better than the PlacementRequiredForWin. RecordPlayerFinish(Player:agent):void= PlayerFinishOrder:int = CurrentFinishOrder set CurrentFinishOrder += 1 if: PointsToAward := PointsPerPlace[PlayerFinishOrder] then: AddPoints(Player, PointsToAward)
Warten, dass Spieler das Rennen beenden
Jetzt, wo du die Aufzeichnung der Statistiken fertig hast, musst du wissen, wann ein Spieler das Rennen beendet, um seine Statistiken zu aktualisieren. Dazu hörst du auf das RaceCompletedEvent() des Rennmanagers. Dieses Event wird immer dann ausgelöst, wenn ein Spieler das Rennen beendet. Du musst also in einer asynchronen Funktion ständig darauf lauschen.
Füge eine neue Funktion
WaitForPlayerToFinishRace()zu deiner Klassendefinitionplayer_leaderboards_examplehinzu. Diese Funktion nimmt einen Spieler entgegen und wartet darauf, dass dieser Spieler das Rennen beendet.Verse# When a player finishes the race, record a finish in their stats table. WaitForPlayerToFinishRace(Player:agent)<suspends>:void=Starte in
WaitForPlayerToFinishRace()in einemrace-Ausdruck zwei Schleifen. Der erste wartet darauf, dass der Spieler das Rennen beendet, und der andere handhabt, was passiert, wenn ein Spieler die Sitzung vor dem Ende verlässt. Wenn ein Spieler aussteigt, willst du nicht, dass die Schleife ewig weiterläuft, also brauchst du eine Möglichkeit, sie in dieser Situation zu verlassen.Verse# When a player finishes the race, record a finish in their stats table. WaitForPlayerToFinishRace(Player:agent)<suspends>:void= race: # Waiting for this player to finish the race and then record the finish. loop: # Waiting for this player to leave the game. loop:Warte in der ersten Schleife auf
RaceManager.RaceCompletedEventund speichere das Ergebnis in einer Variablen mit dem NamenFinishingPlayer. Da dieses Event immer dann ausgelöst wird, wenn ein Spieler das Rennen beendet, musst du sicherstellen, dass es sich bei dem gespeicherten Spieler um den Spieler handelt, den du überwacht hast. Vergleiche denFinishingPlayermit dem Spieler, den diese Schleife überwacht. Wenn die beiden gleich sind, übergib den Spieler anRecordPlayerFinish()und brich die Schleife ab.Verse# Waiting for this player to finish the race and then record the finish. loop: FinishingPlayer := RaceManager.RaceCompletedEvent.Await() if: FinishingPlayer = Player then: RecordPlayerFinish(Player) breakWarte in der zweiten Schleife auf den Spielbereich-Event
PlayerRemovedEvent(). Wie zuvor den Spieler, der gerade gegangen ist, abrufen und in einer VariablenLeavingPlayer. Wenn der Spieler, der das Rennen gerade verlassen hat, der Spieler ist, auf den diese Schleife wartet, dann verlasse die Schleife. Deine fertige FunktionWaitForPlayerToFinishRace()sollte wie folgt aussehen:Verse# When a player finishes the race, record a finish in their stats table. WaitForPlayerToFinishRace(Player:agent)<suspends>:void= race: # Waiting for this player to finish the race and then record the finish. loop: FinishingPlayer := RaceManager.RaceCompletedEvent.Await() if: FinishingPlayer = Player then: RecordPlayerFinish(Player)
Alles miteinander verknüpfen
Wenn du deine Funktionen eingerichtet hast, ist es an der Zeit, sie mit deinen Geräten zu verknüpfen und das Rennen zu starten!
Befolge diese Schritte, um deine Logik mit deinen Geräten zu verknüpfen:
Rufe in
OnBegin()mitGetPlayers()alle Spieler im Spielbereich ab. Übergib dieses Array anInitializeAllPlayerStats(), um dieplayer_stats_tablesfür jeden von ihnen einzurichten.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Get the players in the current race and create a player_stat_table # for each of them. Players := GetPlayspace().GetPlayers() InitializeAllPlayerStats(Players)Rufe
UpdateStatsBillboards()auf, wobei du die ArraysPlayersundLeaderboardsübergibst, um die Reklametafeln im Level mit den aktuellen Daten jedes Spielers zu aktualisieren. Rufe dannUpdatePlayerReferences()auf, um die Referenzen im Level mit den passenden Spielern zu aktualisieren. Spawne schließlich in einemfor-Ausdruck eineWaitForPlayerToFinishRace()-Funktion für jeden Spieler. Deine fertige FunktionOnBegin()sollte wie folgt aussehen:Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Get the players in the current race and create a player_stat_table # for each of them. Players := GetPlayspace().GetPlayers() InitializeAllPlayerStats(Players) UpdateStatsBillboards(Players, Leaderboards) UpdatePlayerReferences(Players, PlayerReferences) # Wait for all players to finish the race.Speichere deinen Code und kompiliere ihn.
Ziehe das Gerät player_leaderboards_example in deinen Level. Weise deine Spielerreferenzen dem Array PlayerReferences zu und achte dabei auf die Reihenfolge. Das Gerät im ersten Index sollte der Spielerreferenz für den besten Spieler entsprechen, der zweite Index für den zweitbesten Spieler und so weiter. Mache das Gleiche für Ranglisten und achte darauf, dass sie auf die Spielerreferenz-Geräte ausgerichtet sind. Vergiss nicht, auch dein Rennmanager-Gerät zuzuweisen!
Testen deiner dauerhaften Ranglisten
Du kannst deine dauerhaften Daten in einer Bearbeitungssitzung testen, aber diese Daten werden zurückgesetzt, wenn du die Sitzung beendest und neu startest. Damit deine Daten über Sitzungen hinweg erhalten bleiben, musst du eine Spieltest-Sitzung starten und bestimmte Einstellungen in deinen Insel-Einstellungen ändern. Informationen zum Einrichten deiner Insel zum Testen von dauerhaften Daten sowohl in Bearbeitungs- als auch in Spieltestsitzungen findest du unter Testen mit dauerhaften Daten und änderst bestimmte Einstellungen in deinen Inseleinstellungen. Informationen zum Einrichten deiner Insel zum Testen von dauerhaften Daten sowohl in Bearbeitungs- als auch in Spieltestsitzungen findest du unter Testen mit dauerhaften Daten.
Nachdem du deine Sitzung eingerichtet hast und deinen Spieltest für das Level durchführst, sollten Spieler, die das Rennen beenden, Punkte auf der Basis ihrer Platzierung erhalten. Sie sollten einen Sieg erhalten, wenn ihre Platzierung hoch genug ist, und diese Statistiken sollten dauerhaft über Spielsessions hinweg gelten. Die Spieler und ihre Statistiken sollten sortiert werden, wobei der Spieler, der die meisten Punkte hat, an erster Stelle steht.
Du bist am Zug
Durch den Abschluss dieses Leitfadens hast du gelernt, wie du Ranglisten erstellst, die dauerhafte Spielerstatistiken in deinem Level anzeigen. Du hast auch gelernt, wie du diese Ranglisten sortierst und aktualisierst, damit jeder erfährt, wer die besten Spieler sind. Versuche, dieses Tutorial an deine eigenen Erlebnisse anzupassen, und zeige die Besten der Besten!
Vollständiger Code
player_stats_table.verse
# This file defines a player_stats_table, a collection of persistable player statistics.
# It also contains functions to compare stats tables by each of the stats to order players
# when sorting.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Structure for passing a player and their stats as arguments.
player_and_stats<public> := struct:
player_leaderboards.verse
# This file contains the code that updates the billboards, player references, and UI on the island
# to display a player's stats from their player stats table. It also handles adding wins and points to a
# player's stats table.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation}
# The message to display on the stats billboard.
StatsMessage<localizes>(CurrentPlayer:message, Points:message, Wins:message):message=
"{CurrentPlayer}:\n{Points}\n{Wins}"
player_stats_manager.verse
# This file handles the code for initializing, updating, and returning player_stats_tables
# for each player. It also defines an abstract stat_type class to use for updating stats, and the
# StatType module to use when displaying stats.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Return the player_stats_table for the provided Agent.
GetPlayerStats<public>(Agent:agent)<decides><transacts>:player_stats_table=
player_leaderboards_example.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { PlayerLeaderboard }
# See https://dev.epicgames.com/documentation/en-us/uefn/create-your-own-device-in-verse for how to create a verse device.
# A Verse-authored creative device that can be placed in a level
player_leaderboards_example := class(creative_device):
# Visual representations of each player.