Molte esperienze utilizzano le statistiche dei giocatori per tenere traccia dei dati relativi alla loro esperienza nel tempo. Statistiche come il punteggio massimo, il totale delle partite vinte, il tempo di gioco totale e gli oggetti raccolti danno ai giocatori un senso di progressione e sono tutti ottimi modi per incoraggiare i giocatori a continuare a giocare.
La persistenza in Verse è un potente strumento che consente di aggiungere dati persistenti agli script Verse. I dati persistenti vengono salvati per giocatore e per isola e rimangono invariati tra le sessioni di gioco. I dati persistenti permettono di tenere traccia dei progressi dei giocatori tra una sessione di gioco e l'altra e apriranno una serie di esperienze di gioco uniche e interessanti precedentemente non disponibili in UEFN.
Questo tutorial mostra come creare una tabella personalizzata di statistiche dei giocatori con Verse e come impostarla in modo che sia persistente tra le varie partite del gioco. Al termine di questo tutorial, consulta Crea la tua classifica di gioco in Verse per imparare come utilizzare la persistenza nelle classifiche di gioco integrate!
Funzionalità del linguaggio Verse utilizzate
Classe: questo esempio crea una classe Verse che gestisce una singola statistica e una classe persistente che tiene traccia di un gruppo di statistiche per un singolo giocatore.
Costruttore: un costruttore è una funzione speciale che crea un'istanza della classe a cui è associato.
Weak_map: una weak_map è una mappa semplice che non può essere iterata. È necessario che i dati persistenti Verse siano memorizzati in una weak_map.
Configurazione del livello
Questo esempio utilizza i seguenti oggetti scenografici e dispositivi.
2 dispositivi Pulsante: quando il giocatore interagisce con il dispositivo, aggiunge un punto al suo punteggio corrente. Userai un altro dispositivo pulsante per simulare la fine di una partita, aggiungendo alle vittorie o alle sconfitte del giocatore un punto a seconda del suo punteggio attuale.
1 dispositivo Billboard: spesso è importante visualizzare dati persistenti al giocatore. A volte questo viene fatto a scopo di test, altre volte per aumentare il coinvolgimento del giocatore o mostrare i progressi. Anche se i requisiti su quando mostrare i dati e quali dati mostrare variano da esperienza a esperienza, in questo esempio verranno mostrati i dati statistici per il punteggio, il punteggio massimo, le vittorie e le sconfitte su un dispositivo billboard.
Tracciamento delle statistiche persistenti del giocatore
Innanzitutto, è importante definire quali statistiche vuoi monitorare per ogni giocatore. Per esempio, potresti voler tenere traccia del punteggio assoluto di un giocatore, della sua posizione attuale o del suo miglior tempo sul giro. In questo esempio, terrai traccia di punteggio, vittorie e sconfitte in una tabella di valori statistici per ogni giocatore. Lo farai in una nuova classe, player_stats_table, che sarà la tua classe persistente principale.
Segui questi step per creare la classe player_stats_table:
Crea un nuovo file Verse utilizzando Verse Explorer chiamato
player_stats_table.verse.Nel nuovo file Verse crea una nuova classe chiamata
player_stats_table. Aggiungi alla classe i modificatori<persistable>e<final>. Il modificatore<persistable>permette ai dati della classe di essere persistenti e richiede il modificatore<final>, perché i dati persistenti non possono essere sovrascritti o sottoclassificati.Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Tracks different persistable stats for each player. player_stats_table := class<final><persistable>:Alla tua
player_stats_table, aggiungi tre valoriintchiamatiPunteggio,VinciteePerdite. Questi valori tengono conto, rispettivamente, del punteggio, delle vittorie e delle sconfitte di ogni giocatore. Inoltre, aggiungi unintchiamatoVersionper tenere traccia della versione attuale della tuaplayer_stats_table.Verse# Tracks different persistable stats for each player. player_stats_table := class<final><persistable>: # The version of the current stats table. Version<public>:int = 0 # The score of a player. Score<public>:int = 0 # The number of wins for a player. Wins<public>:int = 0Per creare un'istanza della
classe player_stats_table, utilizzerai una funzione<constructor>. Questo costruttore è necessario perché la persistenza di Verse non permette la persistenza delle classi contenenti campi variabili. L'utilizzo di un costruttore ti permette di aggiornare i valori persistenti della classe creando una copia di una statistica persistente esistente che è variabile, aggiorna la copia e quindi sostituisci l'istanza originale della classe con i valori modificati. Aggiungi una nuova funzione del costruttoreMakePlayerStatsTable()al file. Questo costruttore prenderà un'istanza originale (precedente) della classeplayer_stats_tablee ne creerà una nuova a partire dai valori originali forniti.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 Score := OldTable.Score Wins := OldTable.Wins Losses := OldTable.LossesPer tenere traccia di tutte le tue
player_stats_tables, utilizzerai unaweak_mappersistente diplayera istanzeplayer_stats_table. Aggiungi questa mappa debole al tuo file.Verse# Maps players to a table of their player stats. var PlayerStatsMap:weak_map(player, player_stats_table) = map{}La tua classe completa
player_stats_tabledeve ora essere simile a questa:Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Tracks different persistable stats for each player. player_stats_table := class<final><persistable>: # The version of the current stats table. Version<public>:int = 0 # The score of a player.
Gestione delle statistiche del giocatore per tutti i giocatori
La tua classe player_stats_table ti permette di tenere traccia delle statistiche di un singolo giocatore, ma non hai ancora un modo per gestirle. Devi aggiornare le tabelle delle statistiche di ogni giocatore ogni volta che guadagna punti e, a seconda del design della tua esperienza, potrebbero esserci più giocatori contemporaneamente.
Per risolvere questo problema, si utilizzerà un'altra classe per gestire le statistiche di tutti i giocatori e registrare le modifiche alle statistiche ogni volta che un giocatore ottiene una vittoria, una sconfitta o un punteggio. Segui i passaggi seguenti per impostare la classe gestione.
Crea un nuovo file Verse usando Verse Explorer chiamato
player_stats_manager.In questo file, crea una nuova classeplayer_stats_manager.Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Manages and updates player_stat_tables for each player. player_stats_manager := class():Il
player_stats_managerdeve fare diverse cose. Deve impostare unaplayer_stats_tableper un giocatore, aggiornarePunteggio,VinciteePerditeper ogni giocatore e restituireplayer_stats_tableper un giocatore. Ciascuna di queste funzioni sarà gestita in modo separato. Aggiungi una nuova funzioneInitializePlayer()alla definizione della classeplayer_stats_manager. Questa funzione inizializzerà le statistiche del giocatore dato.Verse# Initialize stats for the given player. InitializePlayer(Player:player):void=In
InitializePlayer(), controlla se il giocatore dato esiste già nellaPlayerStatsMap. In caso contrario, imposta il valore di quel giocatore nella mappa in una nuovaplayer_stats_table. La funzioneInitializePlayer()completata deve essere simile alla seguente:Verse# Initialize stats for the given player. InitializePlayer(Player:player):void= if: not PlayerStatsMap[Player] set PlayerStatsMap[Player] = player_stats_table{} else: Print("Unable to initialize player stats")Aggiungi una nuova funzione
InitializeAllPlayers()alla definizione della classeplayer_stats_manager. Questa funzione prende un array di giocatori e chiamaInitializePlayer()su tutti loro. La funzioneInitializeAllPlayers()completata deve essere simile alla seguente:Verse# Initialize stats for all current players. InitializeAllPlayers(Players:[]player):void = for (Player : Players): InitializePlayer(Player)Per restituire le statistiche per un determinato giocatore, è necessaria una funzione che restituisca
player_stats_tabledi quel giocatore. Aggiungi una nuova funzioneGetPlayerStats()alla definizione della classeplayer_stats_managerche accetti un agente. Aggiungi il modificatore<decides><transacts>per permettere a questa funzione di avere esito negativo ed eseguire il rollback nel caso in cui la tabella delle statistiche di un giocatore non esista. InGetPlayerStats(), crea una nuova variabileplayer_stats_tablePlayerStats.Verse# Return the player_stats_table for the provided Agent. GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table= var PlayerStats:player_stats_table = player_stats_table{}In un'espressione
if, proietta l'Agentepassato a questa funzione a unGiocatore, quindi recupera laplayer_stats_tableper quel giocatore dallaPlayerStatsMap. Poi impostaPlayerStatssu quella tabella chiamandoMakePlayerStatsTable(). Infine, restituisciPlayerStats. La funzioneGetPlayerStats()completata deve essere simile alla seguente:Verse# Return the player_stats_table for the provided Agent. GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table= var PlayerStats:player_stats_table = player_stats_table{} if: Player := player[Agent] PlayerStatsTable := PlayerStatsMap[Player] set PlayerStats = MakePlayerStatsTable(PlayerStatsTable) PlayerStatsPer aggiornare ciascuna delle statistiche relative a punteggi, vittorie e sconfitte, creerai funzioni per ogni statistica. Aggiungi una nuova funzione denominata
AddScore()al fileplayer_stats_manager. Questa funzione prevede che l'agente assegni il punteggio e il numerointdi punti per assegnarli.Verse# Adds to the given Agent's score and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddScore<public>(Agent:agent, NewScore:int):void=I dati vengono aggiornati prima convalidando che il giocatore abbia dati validi nella
weak_mappersistente e poi sostituendo quei dati con una copia aggiornata della classe. Per gestire il punteggio, recupera il punteggio del giocatore dallaPlayerStatsTable, poi imposta la tabella nellaPlayerStatsMapal risultato di costruire una nuovaplayer_stats_tableutilizzandoMakePlayerStatsTable(), passando il punteggio attuale più il nuovo punteggio. Quando lavori con una classe che contiene più campi, la classe del costruttore ti permette di aggiornare facilmente un singolo campo senza copiare esplicitamente tutti i campi ogni volta che vuoi eseguire un aggiornamento. La tua funzioneAddScore()deve essere simile alla seguente:Verse# Adds to the given Agent's score and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddScore<public>(Agent:agent, NewScore:int):void= if: Player := player[Agent] PlayerStatsTable := PlayerStatsMap[Player] CurrentScore := PlayerStatsTable.Score set PlayerStatsMap[Player] = player_stats_table: MakePlayerStatsTable<constructor>(PlayerStatsTable) Score := CurrentScore + NewScoreRipeti questo processo per le vittorie e le sconfitte, aggiungendo
NewWinseNewLossesrispettivamente alle vittorie o alle sconfitte del giocatore quando chiamiMakePlayerStatsTable().Verse# Adds to the given Agent's wins and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddWin<public>(Agent:agent, NewWins:int):void= if: Player := player[Agent] PlayerStatsTable := PlayerStatsMap[Player] CurrentWins := PlayerStatsTable.Wins set PlayerStatsMap[Player] = player_stats_table: MakePlayerStatsTable<constructor>(PlayerStatsTable) Wins := CurrentWins + NewWinsIl file
player_stats_managerfinale deve essere simile al seguente.Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Manages and updates player_stat_tables for each player. player_stats_manager := class(): # Return the player_stats_table for the provided Agent. GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table= var PlayerStats:player_stats_table = player_stats_table{}
Testare la persistenza con i dispositivi
Ora che sono state impostate le classi di persistenza, è il momento di testarle nel livello.
Crea un nuovo dispositivo Verse denominato player_stats_example. Per informazioni sugli step, vedi Creare il tuo dispositivo utilizzando Verse.
All'inizio della definizione della classe
player_stats_example, aggiungi i seguenti campi:Un
button_devicemodificabile, denominatoScorePointsButton. Questo pulsante aggiunge punti al punteggio del giocatore ogni volta che viene attivato.Verse# Adds to the activating player's score. @editable ScorePointsButton:button_device = button_device{}Un
billboard_devicemodificabile chiamatoStatsBillboard. Questo visualizzerà il punteggio, il punteggio massimo, le vittorie e le sconfitte del giocatore.Verse# Displays the player's Score, High Score, Wins, and Losses @editable StatsBillboard:billboard_device = billboard_device{}Un button_device modificabile chiamato
CheckWinButton. Questo pulsante azzera il punteggio di ogni giocatore e gli assegna una vittoria o una sconfitta a seconda del suo punteggio.Verse# Resets the player's score and award them a win or a loss # depending if their current score is greater than WinScore. @editable CheckWinButton:button_device = button_device{}Un
intmodificabile denominatoWinScore. È il punteggio che i giocatori devono raggiungere per ottenere una vittoria dopo l'attivazione delCheckWinButton.Verse# The score players need to reach to be awarded a win after # the CheckWinButton is activated. @editable WinScore:int = 10Un
intmodificabile denominatoAwardScore. Questi sono i punti che vengono assegnati ai giocatori quando interagiscono con il pulsante.Verse# The amount of score to award per button press. @editable AwardScore:int = 1Un
player_stats_managerchiamatoPlayerStatsManager. Questo gestirà e aggiornerà le statistiche di tutti i giocatori.Verse# Manages and updates stats for each player. PlayerStatsManager:player_stats_manager = player_stats_manager{}Un messaggio chiamato `StatsMessage` che prende un agente e quattro numeri interi: Score, MaxScore, Wins e Losses. Questo messaggio viene utilizzato per visualizzare le statistiche di un giocatore sul billboard.
Verse# Displays a player's stats on a billboard. StatsMessage<localizes>(Player:agent, Score:int, Wins:int, Losses:int):message = "{Player}, Stats:\n Score: {Score}\n Wins: {Wins}\n Losses: {Losses}"
Compila il codice e trascina il tuo dispositivo creato con Verse nella tua isola. Vedi Aggiunta del dispositivo Verse al tuo livello per gli step.
Nel pannello Dettagli del dispositivo, assegna il dispositivo Pulsante del livello a ScorePointsButton e assegna il dispositivo Billboard a StatsBillboard.
Per visualizzare le statistiche di un determinato giocatore su StatsBillboard, aggiungi una nuova funzione
UpdateStatsBillboard()alla definizione della classeplayer_stats_example. Questa funzione prende l'agente di cui visualizzare le statistiche.Verse# Retrieves the stats of the given player and displays their stats # on the StatsBillboard. UpdateStatsBillboard(Agent:agent):void=In
UpdateStatsBillboard(), ottieni le statistiche attuali dell'agente dato chiamando la funzioneGetPlayerStats[]del gestore delle statistiche. Poi chiamaSetText()su StatsBillboard passando un nuovoStatsMessage(). Per costruire questoStatsMessage(), ottieni il punteggio, le vittorie e le sconfitte dell'agente accedendovi dalle statistiche attuali dell'agente. La funzioneUpdateStatsBillboard()completata deve essere simile alla seguente:Verse# Retrieves the stats of the given player and displays their stats # on the StatsBillboard. UpdateStatsBillboard(Agent:agent):void= if: # Get the current stats of the given agent. CurrentPlayerStats := PlayerStatsManager.GetPlayerStats[Agent] then: StatsBillboard.SetText( StatsMessage( Player := Agent,Aggiungi una nuova funzione
AddScore()alla definizione della classeplayer_stats_example. Questa funzione prende un agente e aggiunge al suo punteggio ogni volta che interagisce con il pulsante ScorePointsButton.Verse# Adds to the given player's score and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddScore(Agent:agent):void=In
AddScore(), ottieni le statistiche correnti dell'agente dato e il suo punteggio attuale. Quindi chiamaAddScore()dalPlayerStatsManager, passando l'agente e l'AwardScoreper assegnare loro un nuovo punteggio. Infine, chiamaUpdateStatsBillboard(), passando l'agente dato. La funzioneAddScore()completata deve essere simile alla seguente:Verse# Adds to the given player's score and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddScore(Agent:agent):void= if: CurrentPlayerStats := PlayerStatsManager.GetPlayerStats[Agent] CurrentScore := CurrentPlayerStats.Score then: Print("Current Score is: {CurrentScore}") PlayerStatsManager.AddScore(Agent, AwardScore) UpdateStatsBillboard(Agent)Per assegnare a un giocatore una vittoria o una sconfitta quando si interagisce con il pulsante CheckWin, aggiungi una nuova funzione
CheckWin()alla definizione della classe player_stats_manager.Verse# Awards a player a win or a loss when they interact # with the CheckWinButton. CheckWin(Agent:agent):void=Per prima cosa, definisci una variabile
CurrentScoreper tenere traccia del punteggio attuale dell'agente. Quindi, come con la funzioneAddScore(), recupera il suo punteggio attuale dalla tabella delle statistiche del giocatore.Verse# Awards a player a win or a loss when they interact # with the CheckWinButton. CheckWin(Agent:agent):void= var CurrentScore:int = 0 if: PlayerStats := PlayerStatsManager.GetPlayerStats[Agent] set CurrentScore = PlayerStats.ScoreSe il punteggio attuale dell'agente è maggiore di
WinScore, devi registrare una vittoria nelPlayerStatsManager. In caso contrario, registra una perdita. Infine, azzera il punteggio dell'agente chiamandoAddScore()con unCurrentScorenegativo, quindi visualizza le statistiche dell'agente sul billboard delle statistiche. La funzioneCheckWin()completata deve essere simile alla seguente:Verse# Awards a player a win or a loss when they interact # with the CheckWinButton. CheckWin(Agent:agent):void= var CurrentScore:int = 0 if: PlayerStats := PlayerStatsManager.GetPlayerStats[Agent] set CurrentScore = PlayerStats.Score then: Print("Current Score is: {CurrentScore}") if:In
OnBegin(), sottoscrivi il pulsanteScorePointsButton.InteractedWithEventaAddScore()e il pulsanteCheckWinButton.InteractedWithEventaCheckWin(). Ottieni quindi l'array di ogni giocatore del gioco chiamandoGetPlayers()e inizializzali tutti utilizzando la funzioneInitializeAllPlayers()del gestore delle statistiche.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Register Button Events ScorePointsButton.InteractedWithEvent.Subscribe(AddScore) CheckWinButton.InteractedWithEvent.Subscribe(CheckWin) Players := GetPlayspace().GetPlayers() # Initialize player stats PlayerStatsManager.InitializeAllPlayers(Players)Salva il codice e compilalo.
Testare la persistenza nel livello
Puoi testare i tuoi dati persistenti in una sessione di modifica, ma questi dati verranno ripristinati quando esci e lanci di nuovo la sessione. Per fare in modo che i dati vengano mantenuti da una sessione all'altra, dovrai avviare una sessione di playtest e modificare alcune impostazioni nelle Impostazioni isola. Per sapere di più sulla configurazione della tua isola, e per testare i dati persistenti nelle sessioni di modifica e di playtest, consulta Test con dati persistenti nella pagina dei dati persistenti.
Dopo aver impostato la sessione, durante il playtest del livello, l'interazione con il pulsante ScorePoints deve aggiungere il punteggio del giocatore e visualizzare l'aggiornamento sul billboard. Interagendo con il pulsante CheckWin si aggiungono le vittorie o le sconfitte del giocatore, a seconda del suo punteggio. Una volta tornati nella lobby e rientrati nell'isola, le statistiche del giocatore devono persistere e il totale delle vittorie/perdite e il punteggio più alto devono essere visualizzati sul billboard ogni volta che viene aggiornato.
Ora tocca a te
Al termine di questa guida, hai imparato a usare Verse per creare dati persistenti tracciati per giocatore, che persistono durante le sessioni di gioco. Ora vai a vedere come puoi adattare la persistenza per migliorare la tua esperienza.
Puoi creare un sistema di file di salvataggio che ricordi l'ultimo checkpoint raggiunto dal giocatore?
Che ne dici di un sistema che ricordi con quali personaggi hai parlato e la tua attuale relazione con loro?
Che ne dici di un sistema che dia ai giocatori solo una quantità limitata di tempo, nel corso delle sessioni, per raggiungere gli obiettivi, e che azzeri i loro progressi se non riescono?
Codice completo
Questo è il codice completo compilato in questa sezione del tutorial.
player_stats_table.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Tracks different persistable stats for each player.
player_stats_table := class<final><persistable>:
# The version of the current stats table.
Version<public>:int = 0
# The score of a player.
player_stats_manager.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Manages and updates player_stat_tables for each player.
player_stats_manager := class():
# Return the player_stats_table for the provided Agent.
GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table=
var PlayerStats:player_stats_table = player_stats_table{}
player_stats_example.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# A Verse-authored creative device that can be placed in a level
player_stats_example := class(creative_device):
# Adds to the activating player's score.
@editable