Questa sezione ti mostrerà come determinare e personalizzare i team e le classi dei giocatori.
Dispositivi utilizzati:
-
2 dispositivi Inventario e Impostazioni team
-
2 di Selettore classe
Inventario e Impostazioni team

Usa i dispositivi Inventario e Impostazioni team per impostare i nomi dei team e i colori per la visualizzazione della classifica.
Posiziona un dispositivo per ogni team in un'area non visibile ai giocatori. Per configurare il team oggetti scenografici, imposta le Opzioni utente in modo che corrispondano alla tabella seguente.

Opzione | Valore | Spiegazione |
---|---|---|
Nome team | Oggetti scenografici | Imposta una stringa di testo che verrà utilizzata per identificare il team negli elementi HUD e Classifica. |
Colore team | Blu cielo | Assegna al team selezionato un colore che verrà usato nella classifica, nell'HUD e in certi dispositivi. |
Team | Indice team: 1 | Specifica a quale team si applicano le impostazioni di questo dispositivo. |
Per configurare il team cacciatori, imposta le Opzioni utente dell'altro dispositivo in modo che corrispondano alla tabella seguente.

Opzione | Valore | Spiegazione |
---|---|---|
Nome team | Cacciatori | Imposta una stringa di testo che verrà utilizzata per identificare il team negli elementi HUD e Classifica. |
Colore team | Arancione | Assegna al team selezionato un colore che verrà usato nella classifica, nell'HUD e in certi dispositivi. |
Team | Indice team: 2 | Specifica a quale team si applicano le impostazioni di questo dispositivo. |
Progettista di classi

Usa un Progettista di classi per modificare i team appena creati.
Posiziona due dispositivi Progettista di classi, uno per ogni team, in un'area non visibile ai giocatori. Per personalizzare il team oggetti scenografici, imposta le Opzioni utente in modo che corrispondano alla tabella seguente.
Opzione | Valore | Spiegazione |
---|---|---|
Nome classe | Oggetto scenografico | Determina il nome di questa classe. |
Descrizione classe | Nascondersi dai cacciatori. Sopravvivi. | Imposta la descrizione di questa classe. |
Identificatore di classe | Slot di classe: 1 | Imposta l'identificatore univoco per questa classe. |
Salute max | 1 | Determina il valore massimo di salute che i giocatori possono raggiungere durante la partita. Gli oggetti scenografici saranno eliminati con un solo colpo. |
Elenco degli oggetti | Prop-O-Matic | Imposta l'elenco degli oggetti che questa classe dovrà avere. |
Equipaggia l'oggetto assegnato | Primo oggetto | Determina quale oggetto dell'elenco sarà equipaggiato. |
Per personalizzare il team cacciatori, imposta le Opzioni utente dell'altro dispositivo in modo che corrispondano alla tabella seguente.

Opzione | Valore | Spiegazione |
---|---|---|
Nome classe | Cacciatore | Determina il nome di questa classe. |
Descrizione classe | Trova gli oggetti scenografici. Eliminali. | Imposta la descrizione di questa classe. |
Identificatore di classe | Slot di classe: 2 | Imposta l'identificatore univoco per questa classe. |
Elenco degli oggetti | Pistola torcia | Imposta l'elenco degli oggetti che questa classe dovrà avere. |
Equipaggia l'oggetto assegnato | Primo oggetto | Determina quale oggetto dell'elenco sarà equipaggiato. |
Selettore classe

Abbina il Progettista di classi al Selettore classe per gestire le classi e i team personalizzati che crei.
Oltre a Verse, le impostazioni di questo dispositivo fanno sì che i giocatori nello slot di classe 1 si trasferiscano nello slot di classe 2 quando vengono ri-generati.
Posiziona due dispositivi Selettore classe, uno per ogni team, in un'area non visibile ai giocatori. Per gestire il team oggetti scenografici, utilizza le impostazioni della tabella sottostante per configurare le Opzioni utente di questo dispositivo.

Opzione | Valore | Spiegazione |
---|---|---|
Classe a cui passare | Slot di classe: 1 | Determina a quale classe il giocatore deve passare. |
Visibile durante il gioco | False | Questo dispositivo non è visibile in gioco. |
Audio zona | False | Determina se il Selettore classe deve riprodurre effetti audio quando un giocatore entra nell'area. |
Team a cui passare | Indice team: 1 | Determina a quale team passerà il giocatore. |
Elimina oggetti al cambiamento | True | Determina se gli oggetti devono essere rimossi dall'inventario del giocatore quando il cambiamento viene applicato. |
Volume visibile nel gioco | False | Determina se il volume del dispositivo è visibile durante la partita. |
Trasmetti VFX all'attivazione | False | Determina se il dispositivo deve creare un effetto VFX quando si cambia la classe o il team di un giocatore. |
Per gestire il team cacciatori, utilizza le impostazioni della tabella sottostante per configurare le Opzioni utente di questo dispositivo.

Opzione | Valore | Spiegazione |
---|---|---|
Classe a cui passare | Slot di classe: 2 | Determina a quale classe il giocatore deve passare. |
Team a cui passare | Indice team: 2 | Determina a quale team passerà il giocatore. |
Creare funzionalità per il team con Verse
Ci sono due Team in questo gioco di caccia agli oggetti scenografici: Cacciatori e Oggetti scenografici. Per far funzionare il gioco, devi essere in grado di fare alcune delle stesse cose per entrambi i team. Ad esempio:
-
Aggiungere giocatori a un team
-
Rimuovere i giocatori da un team
-
Visualizzare ai giocatori le informazioni relative al proprio team
Per creare questa funzionalità per entrambi i team senza duplicare il codice, creerai una classe con lo specificatore <abstract>
. Le classi con lo specificatore abstract
sono destinate ad avere funzionalità parziali che le loro sottoclassi ereditano e su cui si basano. Per prima cosa, creerai una classe astratta chiamata base_team
e le assegnerai le funzionalità che saranno condivise da entrambi i team Oggetto scenografico e Cacciatore.
Questo documento include snippet di Verse che mostrano come eseguire le meccaniche di gameplay necessarie in questo gameplay. Segui i passaggi seguenti e copia lo script completo al passaggio 6 di questo tutorial.
Crea un nuovo file Verse nel tuo progetto, denominato base_team.verse. Questo non sarà un dispositivo Verse, quindi puoi crearlo come un file Verse vuoto.
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Colors }
using { /Verse.org/Simulation }
log_team := class(log_channel){}
# Questa classe definisce i dispositivi necessari per i diversi team dell'esperienza.
# Questa classe è astratta e non può essere utilizzata da sola. Deve essere ereditato da un'altra classe.
base_team := class<abstract>:
Logger:log = log{Channel:=log_team}
@editable # Serve a impostare un giocatore nel team.
ClassSelector:class_and_team_selector_device = class_and_team_selector_device{}
@editable # Serve ad assegnare un punteggio agli agenti del team.
ScoreManager:score_manager_device = score_manager_device{}
@editable # Serve a visualizzare il titolo dell'assegnazione al team.
TeamTitle:hud_message_device = hud_message_device{}
@editable # Serve a visualizzare la descrizione dell'assegnazione al team.
TeamDescription:hud_message_device = hud_message_device{}
@editable # Serve a iscriversi agli eventi di eliminazione di un membro del team (team oggetti scenografici) o di un nemico (team cacciatori).
TeamManager:team_settings_and_inventory_device = team_settings_and_inventory_device{}
# È un array di agenti nel team.
var TeamAgents<private>:[]agent = array{}
# Questo evento viene segnalato quando l'array TeamAgents diventa vuoto (segnalando la fine del round).
TeamEmptyEvent:event() = event(){}
# Restituisce l'array di TeamAgents attuale.
# È necessario perché l'array TeamAgents è privato, quindi le altre classi non possono accedervi direttamente.
GetAgents()<decides><transacts>:[]agent =
TeamAgents
# Restituisce la dimensione dell'array TeamAgents
# Richiede una funzione perché l'array TeamAgents è privato, quindi le altre classi non possono accedervi direttamente.
Count()<transacts>:int =
TeamAgents.Length
# Restituisce un indice nell'array TeamAgents di un agente, altrimenti ha esito negativo.
FindOnTeam(Agent:agent)<decides><transacts>: int =
Index := TeamAgents.Find[Agent]
# Imposta l'agente nel team e notifica il giocatore.
InitializeAgent(Agent:agent):void =
AddAgentToTeam(Agent)
ClassSelector.ChangeTeamAndClass(Agent)
DisplayTeamInformation(Agent)
# Aggiungi un agente a TeamAgents.
AddAgentToTeam(AgentToAdd:agent):void =
if (not FindOnTeam[AgentToAdd]):
Logger.Print("Aggiunta di un agente al team.")
set TeamAgents += array{AgentToAdd}
# Attiva i dispositivi di messaggio HUD per mostrare al giocatore in quale team si trova
DisplayTeamInformation(Agent:agent):void =
TeamTitle.Show(Agent)
TeamDescription.Show(Agent)
# Quando un agente lascia la partita, rimuovilo dall'array TeamAgents e controlla la fine del round.
EliminateAgent(Agent:agent)<suspends>:void =
Sleep(0.0) # Ritardo di 1 tick di gioco per assicurarsi che il giocatore sia ri-generato prima di procedere.
RemoveAgentFromTeam(Agent)
# Rimuovi un agente da TeamAgents.
# Se l'agente rimosso era l'ultimo, segnala TeamEmptyEvent.
RemoveAgentFromTeam(AgentToRemove:agent):void =
set TeamAgents = TeamAgents.RemoveAllElements(AgentToRemove)
Logger.Print("{Count()} agente/i rimasto/i nel team.")
if (Count() < 1):
Logger.Print("Non sono rimasti agenti nel team. Il round viene concluso.")
TeamEmptyEvent.Signal()
Ora che hai questa classe, puoi creare le classi per il team oggetti scenografici e il team cacciatori. Poiché ognuno di questi eredita da base_team
, ne derivano alcuni vantaggi:
-
Il codice per l'implementazione di ogni team è molto più breve perché le funzioni e i dati comuni sono già definiti in
base_team
. -
È più facile capire quali codici sono specifici per i team oggetti scenografici e cacciatori perché sono collocati in classi proprie, invece di essere mescolati al codice comune.
-
Aggiungere altri team alla modalità di gioco è molto più facile. Tutti i nuovi team ereditano da
base_team
e il codice che rende diverso il nuovo team si trova nella sua classe.
Ricorda che non puoi creare un'istanza di una classe con lo specificatore <abstract>
. Devi creare una classe che eredita dalla classe abstract e istanziare tale classe.
Team cacciatore
Per prima cosa, crea la classe per il team cacciatori. Crea un nuovo file Verse nel tuo progetto, denominato hunter_team.verse. Questo non sarà un dispositivo Verse, quindi puoi crearlo come un file Verse vuoto.
Dichiara una classe denominata hunter_team
. Deve essere <concrete>
ed ereditare anche da base_team
.
hunter_team := class<concrete>(base_team):
Rendere una classe <concrete>
significa che tutti i Campi della classe devono avere un valore predefinito. Per saperne di più, vedi Specificatori e Attributi.
Di seguito trovi il codice completo dello script hunter_team.verse.
La classe hunter_team
ha due funzioni con lo stesso nome delle funzioni della classe base_team
. Ciò è consentito perché entrambi hanno lo specificatore <override>
. Ciò significa che quando queste funzioni vengono chiamate su un'istanza di hunter_team
, viene utilizzata la versione della classe hunter_team
.
Ad esempio, nel codice seguente verrà utilizzata la versione di InitializeAgent()
definita in hunter_team
perché esegue l'override della funzione con lo stesso nome in base_team
. Confrontala con la chiamata a Count()
che utilizzerà la versione definita in base_team
perché non esiste una funzione di override.
HunterTeam:hunter_team = hunter_team{}
# Utilizza la funzione di hunter_team
HunterTeam.InitializeAgent(StartingHunterAgent)
# Utilizza la funzione di base_team
HunterTeam.Count()
Anche le due funzioni sovrascritte utilizzano (super:)
. Ciò permette loro di chiamare la versione delle funzioni definite in base_team
perché base_team
è la superclasse di hunter_team
. Nel caso di InitializeAgent()
ed EliminateAgent()
, entrambe utilizzano Logger.Print()
per stampare qualcosa nel registro. Poi chiamano le rispettive funzioni da base_team
. Ciò significa che le funzioni operano esattamente come le versioni di base_team
, ad eccezione delle chiamate a Logger.Print()
.
Per saperne di più su <override>
e (super:)
vedi Sottoclasse
Team oggetti scenografici
Ora crea la classe per il team oggetti scenografici. Crea un nuovo file Verse nel tuo progetto, denominato prop_team.verse. Questo non sarà un dispositivo Verse, quindi puoi crearlo come un file Verse vuoto.
I membri del team oggetti scenografici richiedono maggiore gestione. Hanno effetti di battito cardiaco che devono essere avviati e fermati in base a un timer e alla distanza a cui si muovono. Devono anche essere spostati nel team cacciatori, quando vengono eliminati.
Per gestire i membri del team oggetti scenografici, utilizzerai il metodo RunPropGameLoop()
. Puoi pensare a questo metodo come al gestore dell'intero percorso di un oggetto scenografico nel gioco. Dal momento della generazione fino all'eliminazione o all'uscita dal gioco, questo metodo sarà attivo per ogni membro del team oggetti scenografici.
# Se l'agente oggetto scenografico smette di muoversi, allora esegui un'espressione race per vedere se l'agente oggetto scenografico si muove oltre la MinimumMoveDistance, se il timer del battito cardiaco viene completato o se l'agente oggetto scenografico viene eliminato.
RunPropGameLoop(PropAgent:agent)<suspends>:void =
Logger.Print("Avvio loop di gioco dell'agente oggetto scenografico.")
# Esegui un loop infinito del comportamento dell'oggetto scenografico fino a quando l'agente oggetto scenografico viene eliminato o il giocatore abbandona la sessione.
race:
PropAgent.AwaitNoLongerAProp()
loop:
# Attendi che l'agente oggetto scenografico si muova a una distanza inferiore a quella minima, quindi avanza.
PropAgent.AwaitStopMoving(MinimumMoveDistance)
# Finché l'agente oggetto scenografico non si muove oltre la distanza minima, esegui il conto alla rovescia fino al battito cardiaco e poi lo riproduci all'infinito.
race:
PropAgent.AwaitStartMoving(MinimumMoveDistance)
block:
CountdownTimer(PropAgent)
PropAgent.StartHeartbeat()
Sleep(0.0) # Una volta completata l'espressione race (l'agente oggetto scenografico si muove), ricomincia il loop.
RunPropGameLoop()
ha un parametro, PropAgent
. Si tratta di una costante che rappresenta un giocatore del team oggetti scenografici. Ha anche lo specificatore <suspends>
, il che significa che ci vuole tempo per finire. In questo caso, non termina fino a quando il PropAgent
passato non è più nel team oggetti scenografici.
Tutte le funzionalità di questo metodo sono contenute in un'espressione race. Ciò significa che il metodo non sarà completo finché una delle espressioni all'interno di questa espressione race non sarà completata. Tali espressioni sono:
-
PropAgent.AwaitNoLongerAProp()
-
loop
L'espressione loop all'interno di questa espressione race non avrà mai fine. È infinita di proposito. Ciò significa che AwaitNoLongerAProp()
è il metodo che vincerà sempre l'espressione race e completerà il metodo. Usare l'espressione race in questo modo equivale a comunicare al tuo programma di eseguire una certa serie di codice più volte, finché non accade qualcosa. Per saperne di più su questa potente espressione, vedi Race.
Con questo codice, AwaitNoLongerAProp()
risulta l'espressione vincente.
# Esegue un loop fino a quando l'agente oggetto scenografico non fa più parte dell'array PropAgents. La rimozione avviene se l'agente oggetto scenografico viene eliminato e trasformato in un cacciatore o se il giocatore abbandona la sessione.
(PropAgent:agent).AwaitNoLongerAProp()<suspends>:void =
loop:
if (not FindOnTeam[PropAgent]):
Logger.Print("Annullamento del comportamento dell'agente oggetto scenografico.")
break
Sleep(0.0) # Passa al prossimo tick di gioco.
Questo metodo controlla costantemente se PropAgent
è nel team oggetti scenografici. Inizia con un loop che viene eseguito finché not FindOnTeam[PropAgent]
non ha successo e poi si interrompe, completando il metodo. Per saperne di più, vedi Loop e break.
FindOnTeam[]
è una funzione fallibile dichiarata in base_team
. Ha successo se il PropAgent
viene trovato nel team oggetti scenografici. Ma devi usare l'operatore not
perché vuoi uscire dal loop solo quando il PropAgent
non viene trovato nel team oggetti scenografici. Per saperne di più su not
, vedi Operatori.
Infine, devi aggiungere Sleep(0.0)
alla fine del loop. In questo modo si assicura che il loop venga eseguito una volta e poi passi al successivo aggiornamento della simulazione. Non è necessario eseguire questo controllo più spesso, quindi Sleep(0.0)
viene aggiunto per migliorare le prestazioni. Per saperne di più, vedi la pagina guida API di Verse per Sleep.
Ora che sai come funziona AwaitNoLongerAProp()
, puoi scrivere il loop infinito che ci competerà in RunPropGameLoop()
.