Avant de commencer, consultez cette rubrique, car ce tutoriel s'appuie sur les concepts de statistiques de joueur persistantes.
Les classements sont essentiels dans les jeux de compétition, car ils permettent aux gamers de montrer de quoi ils sont capables et de se faire connaître auprès des autres joueurs. Ils aident les joueurs à développer un sens de la progression et les encouragent à rejouer pour se hisser au sommet de la classification.
L'outil Persistance Verse vous permet de créer ces classements et d'ajouter une dimension de compétition à votre expérience. Vous avez déjà vu comment suivre des données persistantes entre les sessions de jeu dans le tutoriel sur les statistiques persistantes des joueurs, et comment modifier et mettre à jour ces données en fonction de différents événements. Vous allez maintenant appliquer ces connaissances pour apprendre à créer des classements locaux complets, à trier les statistiques des joueurs et à intégrer le tout dans un jeu de course.
Fonctionnalités du langage Verse utilisées
Classe : cet exemple crée une classe Verse persistante qui suit un groupe de statistiques pour un joueur donné.
Constructeur : un constructeur est une fonction spéciale qui crée une instance de la classe à laquelle il est associé.
mappage_faible : un weak_map est un mappage simple qui ne peut pas être itéré. Les données persistantes Verse doivent être stockées dans un mappage_faible.
Configurer le niveau
Dans cet exemple, nous utiliserons les accessoires et appareils suivants :
3 panneaux d'affichage : ils permettent d'afficher les statistiques sur la durée de vie de chaque joueur ; vous pouvez les trier en fonction des points de durée de vie pour mettre en valeur les meilleurs joueurs du salon.
3 références de joueur: associées aux panneaux d'affichage, les références de joueur permettent de mettre un visage sur le nom de vos joueurs les plus performants, afin que les autres joueurs sachent à qui ils se mesurent pendant la partie.
3 points de passage : il s'agit des points de passage que les joueurs doivent franchir pour terminer la course.
1 gestionnaire de course : il permet de savoir quand les joueurs commencent et terminent la course, et leur attribue des points en fonction de leur position à l'arrivée.
1 générateur de Bear : il permet de faire apparaître le véhicule que vous utiliserez pendant la course, mais vous pouvez le remplacer par n'importe quel véhicule en fonction de votre expérience.
Pour configurer votre niveau, procédez comme suit :
Panneaux d'affichage et références de joueur
Pour afficher les statistiques des joueurs, utilisez une combinaison de panneaux d'affichage et de références de joueur. Chaque panneau d'affichage présente les statistiques sur la durée de vie d'un joueur ; la référence de joueur est une représentation visuelle du joueur en question. Pour ajouter ces éléments, procédez comme suit :
Ajoutez trois appareils Référence de joueur à votre niveau, et placez-les les uns à côté des autres.
Sélectionnez chaque référence de joueur dans l'organiseur. Dans le panneau Détails, sous Options utilisateur, sélectionnez la couleur souhaitée dans Couleur personnalisée pour représenter les premier, deuxième et troisième joueurs les plus performants dans le salon. Dans cet exemple, nous utilisons les couleurs or, argent et bronze.
Ajoutez trois appareils Panneau d'affichage à votre niveau, et placez-en un devant chaque référence de joueur. Vous les mettrez à jour avec les statistiques de chaque joueur à l'aide de Verse au début de la partie.
Points de passage, Pick-up et Gestionnaire de course
S'agissant d'un jeu de course, vous devez disposer d'éléments de course ! Vous devez également définir des points de passage à franchir et un gestionnaire de course pour diriger la course pendant la partie. Pour ajouter ces éléments, procédez comme suit :
Ajoutez trois points de passage de course à votre niveau. Placez-les dans l'ordre dans lequel vous voulez que les joueurs les franchissent. Pour chaque point de passage, dans l'organiseur, assurez-vous que le numéro du point de passage corresponde à l'ordre dans lequel les joueurs franchissent les points de passage.
Ajoutez un gestionnaire de course à votre niveau. Cet appareil est chargé d'organiser la course et de diriger les joueurs vers les points de passage. Vous écouterez l'événement
RaceCompletedEvent()de cet appareil plus tard pour savoir quand un joueur termine la course.Ajoutez un générateur de Bear à votre niveau. Bien qu'un véhicule soit facultatif, nous utilisons dans ce guide un pick-up conformément au modèle de circuit de course afin que les joueurs puissent suivre une partie du jeu au volant d'un véhicule.
Modifier votre tableau de statistiques
Dans cet exemple, nous utilisons une version modifiée du fichier player_stats_table de la rubrique Statistiques de joueurs persistantes. Ce fichier est similaire à celui de cet exemple, mais présente quelques différences importantes qui modifient la mise en œuvre.
Procédez comme suit pour créer votre tableau de statistiques des joueurs :
Dans votre classe
player_stats_table:Retirez la statistique
Losses.Définissez la statistique
ScoresurPoints.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.
Modifiez la fonction de constructeur
MakePlayerStatsTable()dans votre fichier pour refléter les statistiques mises à jour.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.WinsAjoutez une nouvelle structure
player_and_statsà votre fichier player_stats_table.verse. Cette structure contient une référence à unjoueuret à sa classeplayer_stats_table, pour vous permettre d'utiliser ces deux données dans des fonctions sans avoir besoin de les récupérer à plusieurs reprises. Votre structureplayer_and_statscomplète être similaire à ce qui suit :Verse# Structure for passing a player and their stats as arguments. player_and_stats<public> := struct: Player<public>:player StatsTable<public>:player_stats_table
Gérer les statistiques
Tout comme dans la rubrique Statistiques de joueurs persistantes, vous allez utiliser un fichier de gestionnaire pour gérer et enregistrer les changements de statistiques des joueurs.
Procédez comme suit pour créer votre fichier player_stats_manager modifié.
Remplacez la signature de fonction de
InitializeAllPlayers()etInitializePlayer()parInitializeAllPlayerStats()etInitializePlayerStat(). Ces noms reflètent mieux leur relation avec la fonctionGetPlayerStat(). Votre fonction mise à jour devrait ressembler à ceci :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{}Remplacez la signature de fonction
AddScore()parAddPoints(). Supprimez ensuite la fonctionAddLosses(), car votreplayer_stats_tablene contient plus cette valeur. Votre fichierplayer_stats_managercomplet devrait ressembler à ceci :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=
Créer des classements de joueurs
Vous devez créer certains éléments pour afficher les données des joueurs dans vos classements. Vous devez disposer d'une méthode pour mettre à jour le texte sur les panneaux d'affichage et les joueurs sur les appareils de référence de joueur. Vous devez également disposer d'un moyen de trier ces appareils afin d'identifier clairement les meilleurs joueurs dans votre classement. Dans la mesure où ces fonctions ont un objectif similaire, à savoir la modification des appareils dans le niveau, il est judicieux de les regrouper dans un fichier commun.
Procédez comme suit pour créer des fonctions qui mettent à jour vos appareils dans le niveau :
Créez un nouveau fichier Verse nommé player_leaderboards.verse. Ce fichier stocke les fonctions communes pour mettre à jour vos classements dans le niveau.
En ce qui concerne le texte du panneau d'affichage, vous utiliserez un message auquel vous pouvez transmettre des arguments. Créez un nouveau message nommé
StatsMessagecomprenant les variablesCurrentPlayer,PointsetWins, toutes de typemessage, et qui renvoie le texte combiné sous forme demessage.Verse# The message to display on the stats billboard. StatsMessage<localizes>(CurrentPlayer:message, Points:message, Wins:message):message= "{CurrentPlayer}:\n{Points}\n{Wins}"Ajoutez trois variables
messagesupplémentaires, une pour chacune des entrées deStatsMessage. Le messagePlayerTextindique unAgent, le messagePointsTextles points de cet agent, et le messageWinsTextles victoires de cet agent.StatsMessageva créer un message à partir de tous ces éléments pour afficher proprement vos données dans le niveau.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"Pour mettre à jour un tableau d'affichage, appelez la fonction
UpdateStatsBillboard()du tutoriel Statistiques de joueurs persistantes. Cette fonction étant définie dans un fichier distinct de celui de l'appareil Verse, vous devez ajouter unStatsBillboardcomme argument supplémentaire pour spécifier le tableau d'affichage que vous allez mettre à jour.Verse# Updates the given billboard device to display the stats of the given player. UpdateStatsBillboard<public>(Player:agent, StatsBillboard:billboard_device):void=Tout d'abord, récupérez les statistiques du joueur transmises en tant qu'argument en utilisant
GetPlayerStats[]. Vous n'avez pas besoin d'une référence à unplayer_stats_manager, car il ne s'agit plus d'une classe distincte. Créez ensuite un nouveauStatsMessageen utilisant le joueur et les variablesPointsetWinsde sa classeCurrentPlayerStats. Enfin, appelezSetText()surStatsBillboardpour mettre à jour le texte du tableau d'affichage dans le niveau. Votre fonctionUpdateStatsBillboard()complète devrait ressembler à ceci :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)
Trier et afficher le meilleur joueur
Avant de poursuivre, il est important de réfléchir à la manière dont vous souhaitez trier ces panneaux d'affichage. Quel joueur doit-il décrocher le podium ? Celui qui remporte le plus de points ou celui qui remporte le plus de victoires ? Comment procéder pour obtenir un classement en fonction d'autres statistiques ? Vous devez disposer d'une méthode pour gérer ces aspects : l'algorithme de tri. Grâce à un algorithme de tri et à une fonction de comparaison, vous pouvez spécifier les critères selon lesquels vous souhaitez effectuer le tri. Vous pouvez alors trier vos panneaux d'affichage et vos références de joueur pour afficher les meilleurs joueurs de votre expérience. Dans cet exemple, nous utilisons l'algorithme Merge Sort, mais vous êtes libre d'implémenter celui de votre choix.
Procédez comme suit pour ajouter des fonctions de comparaison et de tri à vos panneaux d'affichage, et terminer la mise à jour des appareils dans votre niveau.
Revenez à votre fichier
player_stats_tablepour définir des fonctions de comparaison pour chacune de vos statistiques. Chacune d'entre elles adopte une structureLeftetRightplayer_and_stats, et les compare sur la base d'une statistique particulière. Ces fonctions possèdent les modificateurs<decides><transacts>, ce qui signifie que si la comparaison échoue, la fonction échouera également, notamment en vous indiquant queLeftest inférieur àRight. Ajoutez une nouvelle fonction nomméeMorePointsComparison()à votre fichier player_stats_table.verse. Cette fonction vérifie siLeft.Pointsest supérieur àRight.Pointset échoue si ce n'est pas le cas. Si elle réussit, elle renvoieLeft`.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 LeftCopiez cette fonction trois fois : une pour comparer le nombre de points inférieur et deux pour comparer les victoires. Vos fonctions de comparaison doivent ressembler à ce qui suit :
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 LeftAjoutez l'algorithme Merge Sort. Vous pouvez le placer dans un fichier ou un module séparé et tester l'algorithme sur le fichier de test fourni.
Lorsque vous revenez dans
player_leaderboards, ajoutez une nouvelle fonctionUpdateStatsBillboards(). Cette fonction utilise une matrice d'agents et une matrice de panneaux d'affichage, les trie et appelleUpdateStatsBillboard()pour mettre à jour chaque panneau d'affichage dans le niveau.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=Dans
UpdateStatsBillboards(), initialisez une nouvelle variable de matrice deplayer_and_statsnomméePlayerAndStatsArray. Définissez-la sur une valeur égale au résultat d'une expressionfor. Dans cette expressionfor, pour chaqueagent, récupérez leplayerpour cetagentet récupérez saplayer_stats_tableà l'aide deGetPlayerStats[]. Puis, renvoyez une structureplayer_and_statscréée à partir duplayeret de sa table de statistiques.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 := PlayerStatsPour trier votre
PlayerAndStatsArray, initialisez une nouvelle variableSortedPlayersAndStatsavec le résultat de l'appel deMergeSort(), en transmettant la matrice etMorePointsComparison. Après un tri dans une expressionfor, itérez sur chaque élément deSortedPlayerAndStats, en stockant l'index des éléments dans une variablePlayerIndex. UtilisezPlayerIndexpour indexer dans la matriceStatsBillboards, puis appelezUpdateStatsBillboarden transmettant le joueur et le panneau d'affichage à mettre à jour. Votre fonctionUpdateStatsBillboards()complète devrait ressembler à ceci :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:Pour mettre à jour vos références de joueur, vous utiliserez une fonction très semblable, appelée
UpdatePlayerReferences(). Cette fonction utilise une matrice deplayer_reference_deviceau lieu de panneaux d'affichage et, au lieu d'appelerUpdateStatsBillboard()à la fin, appelleRegister()sur l'appareil de référence de chaque joueur. Copiez votre codeUpdateStatsBillboard()dans une nouvelle fonctionUpdatePlayerReferences()avec les modifications ci-dessus. Votre fonctionUpdatePlayerReferences()complète devrait ressembler à ceci :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:
Classements des joueurs de votre niveau
Maintenant que tout est en place, il est temps de mettre vos joueurs en valeur ! Vous allez créer un appareil permettant d'attribuer des points aux joueurs lorsqu'ils interagissent avec le bouton, et trier les références de joueur et les panneaux d'affichage pour mettre en avant les meilleurs joueurs. Pour créer un appareil Verse afin de tester les classements de votre niveau, procédez comme suit :
Créez un nouvel appareil Verse nommé player_leaderboards_example. Consultez Créer votre propre appareil avec Verse pour connaître la procédure.
En haut de la définition de la classe
player_leaderboards_example class, ajoutez les champs suivants :Une matrice modifiable d'appareils de référence de joueur nommés
PlayerReferences. Ces derniers fournissent des représentations visuelles de chaque joueur participant à la course.Verse# Visual representations of each player. @editable PlayerReferences:[]player_reference_device = array{}Une matrice modifiable d'appareils de panneau d'affichage nommés
Leaderboards. Ces derniers affichent les statistiques de chaque joueur sur un panneau d'affichage dans le niveau.Verse# Billboards that display each player's stats. @editable Leaderboards:[]billboard_device = array{}Un gestionnaire de course modifiable nommé
RaceManager. Vous vous abonnerez aux événements du gestionnaire de course pour savoir quand un joueur termine la course.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{}Un nombre entier modifiable nommé
PlacementRequiredForWin. Place que doit occuper un joueur pour qu'une victoire lui soit attribuée.Verse# The placement of a player must be at or below to award a win. @editable PlacementRequiredForWin:int = 1Une matrice modifiable de nombres entiers nommée
PointsPerPlace. Nombre de points que chaque joueur gagne en fonction de sa place.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}Une variable de nombre entier nommée
CurrentFinishOrder. Place du dernier joueur à avoir terminé la course.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
Remise de statistiques en fonction de la place
Lorsqu'un joueur termine la course, il est souhaitable de mettre à jour ses statistiques en fonction de sa place. Les joueurs bien classés doivent recevoir un nombre de points plus élevé. Ceux qui ont obtenu les meilleures places doivent recevoir une victoire.
Pour attribuer des statistiques aux joueurs lorsqu'ils terminent la course, procédez comme suit :
Ajoutez une nouvelle fonction
RecordPlayerFinish()à votre définition de classeplayer_leaderboards_example. Cette fonction utilise le joueur à qui attribuer des statistiques comme paramètre.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=Dans
RecordPlayerFinish(), obtenez la place de ce joueur en récupérant la valeur actuelle deCurrentFinishOrderdans un nouveauintnomméPlayerFinishOrder. Ensuite, incrémentezCurrentFinishOrderafin que le prochain joueur qui termine n'occupe pas la même place.VerseRecordPlayerFinish(Player:agent):void= PlayerFinishOrder:int = CurrentFinishOrder set CurrentFinishOrder += 1Le moment est venu d'attribuer des statistiques. Pour savoir combien de points attribuer à ce joueur, dans une expression
if, indexez-le dans la matricePointsPerPlaceà l'aide dePlayerFinishOrder. Puis, appelezAddPoints()pour attribuer ce nombre de points à ce joueur.Verseset CurrentFinishOrder += 1 if: PointsToAward := PointsPerPlace[PlayerFinishOrder] then: AddPoints(Player, PointsToAward)Si la place du joueur était suffisamment élevée pour obtenir une victoire, vous devez enregistrer une victoire dans sa table de statistiques. Dans une autre expression
if, vérifiez siPlayerFinishOrderétait inférieur àPlacementRequiredToWin. Si c'est le cas, appelezAddWin()en transmettant le joueur et une victoire à lui attribuer. Votre fonctionRecordPlayerFinish()complète doit ressembler à ceci :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)
Attendre la fin de la course
Maintenant que l'enregistrement des statistiques est prêt, vous devez savoir quand un joueur termine la course pour mettre à jour ses statistiques. Pour cela, vous écouterez l'événement RaceCompletedEvent() du gestionnaire de course. Cet événement se déclenche chaque fois qu'un joueur termine la course. Vous devrez donc l'écouter en continu dans une fonction asynchrone.
Ajoutez une nouvelle fonction
WaitForPlayerToFinishRace()à la définition de votre classeplayer_leaderboards_example. Cette fonction utilise un joueur et attend qu'il termine la course.Verse# When a player finishes the race, record a finish in their stats table. WaitForPlayerToFinishRace(Player:agent)<suspends>:void=Dans
WaitForPlayerToFinishRace(), dans une expressionrace, démarrez deux boucles. La première attendra que le joueur termine la course, tandis que l'autre gérera ce qu'il advient si un joueur quitte la session avant de terminer. Si un joueur part, la boucle ne doit pas continuer à tourner indéfiniment. Il faut donc trouver un moyen d'en sortir dans ce type de situation.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:Dans la première boucle, attendez l'événement
RaceManager.RaceCompletedEventet stockez le résultat dans une variable nomméeFinishingPlayer. Étant donné que cet événement se déclenche chaque fois qu'un joueur termine la course, assurez-vous que le joueur que vous avez enregistré est bien celui que vous étiez en train de surveiller. Comparez leFinishingPlayerau joueur que cette boucle surveille. Si les deux sont égaux, transmettez le joueur àRecordPlayerFinish()et rompez la boucle.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) breakDans la deuxième boucle, attendez l'événement
PlayerRemovedEvent()de l'espace de jeu. Comme précédemment, récupérez le joueur qui vient de partir et stockez-le dans une variableLeavingPlayer. Si le joueur qui vient de partir est celui que cette boucle attend, rompez la boucle. Votre fonctionWaitForPlayerToFinishRace()complète doit ressembler à ceci :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)
Chaîner le tout ensemble
Une fois vos fonctions configurées, il est temps de les lier à vos appareils et de commencer la course !
Pour lier votre logique à vos appareils, procédez comme suit :
Dans
OnBegin(), récupérez tous les joueurs de l'espace de jeu à l'aide deGetPlayers(). Transmettez cette matrice àInitializeAllPlayerStats()afin de configurerplayer_stats_tablespour chacun d'eux.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)Appelez
UpdateStatsBillboards()en transmettant les matricesPlayersetLeaderboardspour mettre à jour les panneaux d'affichage du niveau selon les données actuelles de chaque joueur. Puis, appelezUpdatePlayerReferences()pour mettre à jour les références du niveau afin qu'elles correspondent aux joueurs. Pour finir, dans une expressionfor, générez une fonctionWaitForPlayerToFinishRace()pour chaque joueur. Votre fonctionOnBegin()doit ressembler à ce qui suit :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.Enregistrez votre code et compilez-le.
Faites glisser l'appareil player_leaderboards_example dans votre niveau. Affectez vos références de joueur à la matrice PlayerReferences, en gardant une trace de l'ordre. L'appareil du premier index doit correspondre à la référence du meilleur joueur, le deuxième index au deuxième meilleur joueur, etc. Procédez de la même manière pour les classements, en veillant à conserver leur alignement avec les appareils de référence de joueur. Pensez également à assigner votre gestionnaire de course !
Tester vos classements persistants
Vous pouvez tester vos données persistantes dans une session de modification, mais ces données seront réinitialisées lorsque vous quitterez la session et la relancerez. Pour conserver vos données d'une session à l'autre, vous devrez lancer une session de test de jeu et modifier certains paramètres de l'île. Pour plus d'informations sur la configuration de votre île et tester les données persistantes dans les sessions de modification et de test, consultez la rubrique Tester avec des données persistantes et modifiez certains paramètres de l'île. Pour plus d'informations sur la configuration de votre île pour tester les données persistantes dans les sessions d'édition et dans les sessions de test, consultez la rubrique Tester avec des données persistantes.
Une fois votre session configurée, lorsque vous testez votre niveau, les joueurs qui terminent la course doivent recevoir des points en fonction de leur place. Ils doivent se voir attribuer une victoire si leur classement est suffisamment élevé, et ces statistiques doivent persister au fil des sessions de jeu. Les joueurs et leurs statistiques doivent être triés, celui ayant le plus de points apparaissant en premier.
À vous de jouer
Au cours de ce tutoriel, vous avez appris à créer des classements qui présentent les statistiques persistantes des joueurs de votre niveau. Vous avez également appris à trier et à mettre à jour ces classements, en vous assurant que tout le monde sache qui sont les meilleurs joueurs. Essayez d'adapter ce tutoriel à vos propres expériences et mettez en valeur les champions !
Code complet
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.