Questo tutorial utilizza Verse per rendere possibili alcune funzionalità. Utilizzando Verse in questo tutorial, potrai:
-
Attivare e riprodurre animazioni a intermittenza per creare una meccanica di gameplay.
-
Aggiornare le informazioni di punteggio per tutti i giocatori di un minigioco.
-
Creare ritardi nella generazione dei giocatori e tempi di generazione intermittente degli oggetti.
Puoi riutilizzare questo codice per eseguire le seguenti operazioni:
-
Commutare i dispositivi abilitati e disabilitati mentre il gioco passa dall'HUB al gameplay e di nuovo all'HUB.
-
Controllare i punteggi dei giocatori per trovare il punteggio vincente e visualizzarlo nell'HUB.
-
Terminare il gioco e teletrasportare i giocatori all'HUB alla fine del minigioco.
Configurazione del dispositivo Verse e degli oggetti modificabili
Segui questi passaggi per configurare il tuo dispositivo Verse e gli oggetti modificabili:
-
Crea un nuovo dispositivo Verse denominato
tiltnboom
e aggiungilo al livello. Per informazioni sui passaggi, vedi Creare un dispositivo personalizzato utilizzando Verse. -
Aggiungi i seguenti moduli all'inizio del file:
using { /Fortnite.com/Characters } using { /Fortnite.com/Devices } using { /Fortnite.com/Game } using { /UnrealEngine.com/Temporary/Diagnostics } using { /Verse.org/Random } using { /Verse.org/Simulation }
- Aggiungi i seguenti campi alla definizione di classe
tiltnboom
:-
Due dispositivi
trigger
modificabili: ActivateGameTrigger e EndGameTrigger.ActivateGameTrigger
permette di attivare il gioco. Il trigger può essere attivato da qualsiasi cosa, ad esempio un teletrasporto verso il gioco o dopo una cinematica introduttiva.EndGameTrigger
permette di terminare il minigioco e rimuovere tutte le telecamere e i dispositivi di controllo dai giocatori al termine della partita.
@editable ActivateGameTrigger:trigger_device = trigger_device{} @editable EndGameTrigger:trigger_device = trigger_device{}
-
Dispositivo Timer modificabile denominato GameTimer. Permette di terminare il gioco dopo un determinato periodo di tempo.
-
array
di dispositivi Sequenza cinematica denominatoCannonballSequences
. Ogni dispositivo dell'array riproduce una diversa posizione di atterraggio della palla di cannone. -
Array di Volumi di danni denominato DamageVolumes che si attiva e disattiva in base allo stato di gioco.
-
Array di Generatori oggetti denominato ItemSpawner che genera un numero casuale di oggetti durante la partita.
-
Dispositivo Area di acquisizione denominato CaptureArea. Assegna ai giocatori dei punti per la presenza sulla zattera e si attiva o disattiva in base allo stato di gioco.
-
Dispositivo Gestione punteggio denominato
ScoreManager
che reimposta il punteggio dei giocatori all'inizio della partita e ne determina il giocatore vincitore al termine. -
Teletrasporto chiamato
HUBTeleporter
che riporta tutti all'HUB al termine della partita. -
Dispositivo Riferimento giocatore denominato PlayerReference che visualizza il giocatore vincitore nell'HUB tra una partita e l'altra.
@editable GameTimer:timer_device = timer_device{} @editable CannonballSequences:[]cinematic_sequence_device = array{} @editable DamageVolumes:[]damage_volume_device = array{} @editable ItemSpawners:[]item_spawner_device = array{} @editable CaptureArea:capture_area_device = capture_area_device{} @editable ScoreManager:score_manager_device = score_manager_device{} @editable HUBTeleporter:teleporter_device = teleporter_device{} @editable PlayerReference:player_reference_device = player_reference_device{}
-
-
Due array modificabili di Pedane di generazione giocatore denominati
PlayerSpawners
eHUBSpawners
. Questi array disattivano la generazione al termine del minigioco e riportano i giocatori all'HUB.@editable PlayerSpawners:[]player_spawner_device = array{} @editable HUBSpawners:[]player_spawner_device = array{}
-
Due
float
modificabili denominatiMinimumItemSpawnTime
eMaximumItemSpawnTime
. Indicano il tempo di attesa minimo e massimo tra le generazioni di oggetti sulla zattera.@editable MinimumItemSpawnTime:float = 5.0 @editable MaximumItemSpawnTime:float = 10.0
-
float
modificabile denominatoDelayAfterGame
. Indica il ritardo per il teletrasporto dei giocatori nell'HUB una volta terminata la partita.@editable DelayAfterGame:float = 5.0
-
float
denominatoDelayBetweenCannonballSequences
. È il ritardo con cui vengono riprodotte le palle di cannone tra le sequenze per tutta la durata del minigioco.DelayBetweenCannonballSequences:float = 8.0
-
Variabile logica denominata
GameActive
per determinare se il gioco è attivo o meno.var GameActive:logic = false
Avvio del gioco
All'avvio del minigioco vengono attivati diversi dispositivi e il punteggio del giocatore viene reimpostato su 0.
-
Sopra la definizione della classe
tiltnboom
, aggiunge un canale di registro per la stampa dei messaggi specifici del minigioco. Poi aggiunge un logger alla definizione della classe da utilizzare con il canale di registro.tiltnboom_log_channel := class(log_channel){} # Dispositivo di Fortnite Creativo sviluppato con Verse che può essere inserito in un livello tiltnboom := class(creative_device): Logger:log = log{Channel := tiltnboom_log_channel}
-
Aggiunge un nuovo metodo
OnTriggered
alla definizione della classetiltnboom
che prende unInitiatingAgent
e avvia il gioco. Aggiunge un'espressioneif
al metodo che restituisce se il gioco è già attivo in modo da non avviarlo se è già in esecuzione.OnTriggered(InitiatingAgent:?agent):void= if (GameActive?): return spawn{StartGame()}
-
In
OnBegin()
, iscriveTriggeredEvent
di ActivateGameTrigger alla funzioneOnTriggered
per avviare il gioco. I dispositivi da abilitare all'inizio del minigioco verranno iscritti a questo evento e si abilitano quando l'evento OnTrigger viene attivato.OnBegin<override>()<suspends>:void= ActivateGameTrigger.TriggeredEvent.Subscribe(OnTriggered)
-
Aggiunge un nuovo metodo
StartGame()
che gestisce la logica di avvio del gioco. Aggiungi il modificatore<suspends>
a questa funzione in modo che possa essere eseguita in modo asincrono.Per prima cosa, imposta
GameActive
sutrue
per segnalare che la partita è attiva. Poi attivaCaptureArea
e ogniDamageVolume
nell'arrayDamageVolumes
.Per ogni giocatore: se quel giocatore ha un punteggio superiore a 0, lo reimposta assegnandogli l'inverso del suo punteggio attuale per ottenere 0.
Quindi, in un'espressione race, corre tra il timer che termina, la sequenza di palle di cannone in esecuzione e la generazione di oggetti casuali. La sequenza di palle di cannone e la generazione di oggetti casuali sono loop infiniti, ma vengono annullati appena il timer termina.
Al termine del gioco, chiama la funzione
OnGameFinished()
per gestire la pulizia alla fine del gioco.StartGame()<suspends>:void= Logger.Print("Avvio della partita.") set GameActive = true CaptureArea.Enable() for (DamageVolume : DamageVolumes): DamageVolume.Enable() for: Player : GetPlayspace().GetPlayers() PlayerScore := ScoreManager.GetCurrentScore(Player) PlayerScore > 0 do: ScoreManager.SetScoreAward(-PlayerScore) ScoreManager.Activate(Player) race: GameTimer.SuccessEvent.Await() StartCannonSequence() SpawnRandomItems() OnGameFinished()
Creazione di un loop per le palle di cannone
Questa sezione tratta l'aggiunta di una funzione che riproduce le Sequenze cinematiche delle palle di cannone.
-
Aggiungi un nuovo metodo
StartCannonSequence()
alla definizione della classetiltnboom
che riproduce le sequenze di livelli delle palle di cannone e utilizza un loop per riprodurre l'espressione delay e inserire un ritardo tra le palle di cannone. Aggiungi il modificatore<suspends>
a questa funzione in modo che possa essere eseguita in modo asincrono.In un loop, scegli una sequenza casuale nell'array
CannonballSequences
indicizzandola conGetRandomInt()
. Riproduci la sequenza, poi resta in sospensione per un determinato periodo di tempoDelayBetweenCannonballSequences
prima di riprodurre un'altra sequenza.StartCannonSequence()<suspends>:void= loop: RandomCannonballSequence:int = GetRandomInt(0, CannonballSequences.Length - 1) if (CannonballSequence := CannonballSequences[RandomCannonballSequence]): Logger.Print("Imposta CannonballSequence su {RandomCannonballSequence}") CannonballSequence.Play() Sleep(DelayBetweenCannonballSequences)
Creazione di loop di oggetti con generazione casuale
Questa sezione tratta la creazione di una funzione che genera in loop oggetti casuali in punti casuali della zattera che possono aumentare o diminuire le probabilità di vittoria di un giocatore nel minigioco.
-
Aggiungi un nuovo metodo denominato
SpawnRandomItems
alla definizione della classetiltnboom
. Questo metodo controlla gli oggetti che vengono generati sulla zattera. -
Determina il numero di oggetti nell'array
ItemSpawners
, quindi esegui un loop nell'array. Utilizza unint
casuale per ottenere un generatore di oggetti casuali dall'array, quindi attivalo. Resta in sospensione per un periodo di tempo casuale tra le generazioni degli oggetti. -
Il loop decide in modo casuale quanti elementi riprodurre e seleziona casualmente un elemento da riprodurre per un numero di volte pari a
NumberOfItemsToSpawn
.DelayBetweenItemSpawns
genera un tempo di attesa indeterminato tra una generazione e l'altra.SpawnRandomItems()<suspends>:void= ItemSpawnerCount:int = ItemSpawners.Length - 1 loop: NumberOfItemsToSpawn:int = GetRandomInt(0, ItemSpawnerCount) # Genera un oggetto selezionato casualmente un numero di volte pari a NumberOfItemsToSpawn. for: CurrentItemSpawnNumber := 0..NumberOfItemsToSpawn RandomItemToSpawn:int = GetRandomInt(0, ItemSpawnerCount) SelectedItemSpawner := ItemSpawners[RandomItemToSpawn] do: SelectedItemSpawner.SpawnItem() Logger.Print("Oggetti casuali generati.") DelayBetweenItemSpawns:float = GetRandomFloat(MinimumItemSpawnTime, MaximumItemSpawnTime)
Termine del gioco
Al termine del minigioco dovrai inviare il punteggio del vincitore all'HUB, disattivare i dispositivi e teletrasportare i giocatori nell'HUB.
-
Aggiungi un nuovo metodo
OnGameFinished
alla definizione della classetitlnboom
. Quando il gioco è terminato, questa funzione imposta il gioco come inattivo e disabilita i relativi dispositivi.OnGameFinished()<suspends>:void= Logger.Print("Partita terminata.") set GameActive = false CaptureArea.Disable() for (PlayerSpawner : PlayerSpawners): PlayerSpawner.Disable() for (DamageVolume : DamageVolumes): DamageVolume.Disable()
-
Aggiungi la
variable int
HighestScore
per tenere traccia del giocatore con il punteggio più alto e un riferimento variabile opzionale a quel giocatoreWinningPlayer
.var HighestScore:int = -1 var WinningPlayer:?agent = false
-
In un'espressione
for
/do, ottieni tutti i giocatori nello spazio di gioco, quindi ottieniFortCharacter
per ciascuno di essi. Congela il personaggio in posizione conPutInStasis()
, passando una nuova serie distasis_args
per permettere di girarsi e utilizzare emote in modo che i giocatori possano festeggiare la partita.for: Player : GetPlayspace().GetPlayers() FortCharacter := Player.GetFortCharacter[] do: FortCharacter.PutInStasis(stasis_args{AllowTurning := true, AllowEmotes := true})
-
In un'istruzione
if
, controlla il punteggio di ogni giocatore per trovare e memorizzare il punteggio vincente nel dispositivo Riferimento giocatore nell'HUB.if (ScoreManager.GetCurrentScore(Player) > HighestScore): set HighestScore = ScoreManager.GetCurrentScore(Player) set WinningPlayer = option{Player}
-
Infine, in un'altra istruzione if, chiama
TeleportPlayersToHUB()
per teletrasportare tutti all'HUB quando viene trovato un punteggio vincente.if(Winner := WinningPlayer?): PlayerReference.Register(Winner) TeleportPlayersToHUB()
Teletrasporto dei giocatori nell'HUB
Quando i punteggi sono stati calcolati e viene dichiarato un vincitore, tutti i giocatori devono essere teletrasportati nell'HUB.
-
Aggiungi un nuovo metodo
TeleportPlayersToHUB()
alla definizione della classetitlnboom
. Questo metodo abilita tutti i Generatori giocatori nell'HUB, quindi attende qualche secondo prima di teletrasportarli tutti nell'HUB. Questo metodo deve anche attivareEndGameTrigger
per rimuovere la telecamera e i dispositivi di controllo dai giocatori.TeleportPlayersToHUB()<suspends>:void= for (HUBSpawner : HUBSpawners): HUBSpawner.Enable() Sleep(DelayAfterGame) EndGameTrigger.Trigger()
-
In un'espressione
for
, teletrasporta ogni giocatore all'HUBTeleporter
e li libera dalla stasi.for: Player : GetPlayspace().GetPlayers() FortCharacter := Player.GetFortCharacter[] do: HUBTeleporter.Teleport(Player) Sleep(1.0) FortCharacter.ReleaseFromStasis()
In autonomia
Modifica questo codice per creare diversi task da far eseguire al dispositivo Timer. Invece di determinare la durata di un minigioco, puoi utilizzare il dispositivo Timer per cronometrare una corsa.
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Random }
using { /Verse.org/Simulation }
tiltnboom_log_channel := class(log_channel){}
# Dispositivo di Fortnite Creativo sviluppato con Verse che può essere inserito in un livello
tiltnboom := class(creative_device):
Logger:log = log{Channel := tiltnboom_log_channel}
# Trigger utilizzato per attivare questo gioco. Il trigger può essere attivato da qualsiasi cosa, ad esempio un teletrasporto verso il gioco o dopo una cinematica introduttiva.
@editable
ActivateGameTrigger:trigger_device = trigger_device{}
# Trigger utilizzato per terminare questo gioco. Viene utilizzato per rimuovere la telecamera e i dispositivi di controllo dai giocatori al termine della partita.
@editable
EndGameTrigger:trigger_device = trigger_device{}
# Il dispositivo Timer viene utilizzato per terminare il gioco dopo un determinato periodo di tempo.
@editable
GameTimer:timer_device = timer_device{}
# Array di sequenze in cui ogni sequenza rappresenta una diversa posizione di atterraggio della palla di cannone.
@editable
CannonballSequences:[]cinematic_sequence_device = array{}
# Array di Volumi di danni utilizzato per attivarli e disattivarli in base allo stato di gioco.
@editable
DamageVolumes:[]damage_volume_device = array{}
# Array di Generatori giocatori per questa partita, viene utilizzato per disabilitarli quando la partita è finita.
@editable
PlayerSpawners:[]player_spawner_device = array{}
# Array di Generatori giocatori nell'HUB, viene utilizzato per abilitarli al termine della partita in modo che i giocatori possano tornare all'HUB.
@editable
HUBSpawners:[]player_spawner_device = array{}
# Array di Generatori oggetti che genera un numero casuale di oggetti durante la partita.
@editable
ItemSpawners:[]item_spawner_device = array{}
# Dispositivo Area di acquisizione che assegna ai giocatori dei punti per la presenza sulla zattera. Viene utilizzato per attivarla e disattivarla in base allo stato di gioco.
@editable
CaptureArea:capture_area_device = capture_area_device{}
# Il dispositivo Gestione punteggio viene utilizzato per reimposta il punteggio dei giocatori all'inizio della partita e determina il giocatore vincitore al termine della stessa.
@editable
ScoreManager:score_manager_device = score_manager_device{}
# Teletrasporto utilizzato per riportare tutti all'HUB al termine della partita.
@editable
HUBTeleporter:teleporter_device = teleporter_device{}
# Tempo minimo tra le generazioni di oggetti casuali.
@editable
MinimumItemSpawnTime:float = 5.0
# Tempo massimo tra le generazioni di oggetti casuali.
@editable
MaximumItemSpawnTime:float = 10.0
# Dispositivo Riferimento giocatore utilizzato per visualizzare il giocatore vincitore nell'HUB tra una partita e l'altra.
@editable
PlayerReference:player_reference_device = player_reference_device{}
# Tempo di attesa dopo la fine della partita prima di teletrasportare tutti nell'HUB.
@editable
DelayAfterGame:float = 5.0
# Quantità di tempo di attesa tra le sequenze di palle di cannone.
DelayBetweenCannonballSequences:float = 8.0
# Variabile logica globale per stabilire se il gioco è attivo o meno.
var GameActive:logic = false
OnBegin<override>()<suspends>:void=
# Sottoscrivi il TriggeredEvent ActivateGameTrigger in modo che il dispositivo possa avviare il gioco quando viene attivato.
ActivateGameTrigger.TriggeredEvent.Subscribe(OnTriggered)
# Avvia il gioco quando ActivateGameTrigger viene attivato
# se il gioco non è già attivo.
OnTriggered(InitiatingAgent:?agent):void=
# Non avviare il gioco se è già in esecuzione.
if (GameActive?):
return
spawn{StartGame()}
# Se il gioco non era attivo ed è stato avviato, imposta il gioco come attivo e abilita i dispositivi per la partita.
# Quindi, reimposta il punteggio di tutti i giocatori, sottoscrivi l'evento SuccessEvent del dispositivo Timer per terminare la partita allo scadere del tempo,
# inizia a sparare palle di cannone ai giocatori e a generare oggetti casuali.
StartGame()<suspends>:void=
Logger.Print("Avvio della partita.")
set GameActive = true
# Abilita i dispositivi utilizzati nel gioco.
CaptureArea.Enable()
for (DamageVolume : DamageVolumes):
DamageVolume.Enable()
# Per ogni giocatore: se quel giocatore ha un punteggio superiore a 0, lo reimposta assegnandogli l'inverso del suo
# punteggio per ottenere 0.
for:
Player : GetPlayspace().GetPlayers()
PlayerScore := ScoreManager.GetCurrentScore(Player)
PlayerScore > 0
do:
ScoreManager.SetScoreAward(-PlayerScore)
ScoreManager.Activate(Player)
# Corre tra il timer che termina, la sequenza di palle di cannone in esecuzione e la generazione di oggetti casuali.
# La sequenza di palle di cannone e la generazione di oggetti casuali sono loop infiniti, ma verranno annullati al termine del timer.
race:
GameTimer.SuccessEvent.Await()
StartCannonSequence()
SpawnRandomItems()
# La partita è finita perché il timer è terminato. Gestisci i giocatori in movimento e registra il giocatore che ha vinto.
OnGameFinished()
# Se il gioco diventa inattivo durante il loop, esci dal loop e smetti di sparare palle di cannone.
# Altrimenti, scegli a caso una sequenza nell'array e riproducila, quindi attendi otto secondi prima di riprodurre un'altra sequenza.
StartCannonSequence()<suspends>:void=
loop:
# Scegli una sequenza a caso tra le sequenze di palle di cannone da riprodurre.
RandomCannonballSequence:int = GetRandomInt(0, CannonballSequences.Length - 1)
if (CannonballSequence := CannonballSequences[RandomCannonballSequence]):
Logger.Print("Imposta CannonballSequence su {RandomCannonballSequence}")
# Riproduce la sequenza di palle di cannone selezionata casualmente
CannonballSequence.Play()
# Attendi DelayBetweenCannonBallSequences secondi prima della sequenza successiva.
Sleep(DelayBetweenCannonballSequences)
# Ottieni la lunghezza dell'array ItemSpawners, quindi esegui un loop nell'array e attiva un numero casuale di generatori di oggetti.
# Attendi un intervallo di tempo casuale tra la generazione degli oggetti e ripeti fino a quando il gioco non diventa inattivo.
SpawnRandomItems()<suspends>:void=
ItemSpawnerCount:int = ItemSpawners.Length - 1
loop:
# Decidi quanti oggetti generare questa volta, in modo casuale.
NumberOfItemsToSpawn:int = GetRandomInt(0, ItemSpawnerCount)
# Genera un oggetto selezionato casualmente un numero di volte pari a NumberOfItemsToSpawn.
for:
CurrentItemSpawnNumber := 0..NumberOfItemsToSpawn
RandomItemToSpawn:int = GetRandomInt(0, ItemSpawnerCount)
SelectedItemSpawner := ItemSpawners[RandomItemToSpawn]
do:
SelectedItemSpawner.SpawnItem()
# Genera un tempo di attesa casuale tra le generazioni degli oggetti.
Logger.Print("Oggetti casuali generati.")
DelayBetweenItemSpawns:float = GetRandomFloat(MinimumItemSpawnTime, MaximumItemSpawnTime)
# Attendi DelayBetweenItemSpawns secondi
Sleep(DelayBetweenItemSpawns)
# Quando il gioco è terminato, questa funzione lo imposta come inattivo e disabilita i relativi dispositivi.
# Poi, trova il giocatore vincitore e imposta il dispositivo Riferimento giocatore su quel giocatore.
# Infine, teletrasporta tutti all'HUB.
OnGameFinished()<suspends>:void=
Logger.Print("Partita terminata.")
set GameActive = false
# Disattiva i dispositivi utilizzati nel gioco.
CaptureArea.Disable()
for (PlayerSpawner : PlayerSpawners):
PlayerSpawner.Disable()
for (DamageVolume : DamageVolumes):
DamageVolume.Disable()
# Ottieni i giocatori con il punteggio più alto e memorizzalo nel dispositivo Riferimento giocatore.
var HighestScore:int = -1
var WinningPlayer:?agent = false
for:
Player : GetPlayspace().GetPlayers()
FortCharacter := Player.GetFortCharacter[]
do:
# Congela il giocatore.
FortCharacter.PutInStasis(stasis_args{AllowTurning := true, AllowEmotes := true})
# Controlla se il punteggio di questo giocatore è superiore al punteggio più alto attualmente trovato.
if (ScoreManager.GetCurrentScore(Player) > HighestScore):
# Aggiorna il punteggio più alto e il giocatore vincente
set HighestScore = ScoreManager.GetCurrentScore(Player)
set WinningPlayer = option{Player}
if(Winner := WinningPlayer?):
PlayerReference.Register(Winner)
TeleportPlayersToHUB()
# Abilita tutti i Generatori giocatori nell'HUB, quindi attendi qualche secondo prima di teletrasportare tutti nell'HUB.
# Inoltre, attiva EndGameTrigger per rimuovere la telecamera e i dispositivi di controllo dai giocatori.
TeleportPlayersToHUB()<suspends>:void=
# Abilita i generatori dell'HUB.
for (HUBSpawner : HUBSpawners):
HUBSpawner.Enable()
# Ritardo dopo la fine del gioco.
Sleep(DelayAfterGame)
# Informa gli altri dispositivi della fine del gioco.
EndGameTrigger.Trigger()
# Sposta tutti i giocatori nell'HUB.
for:
Player : GetPlayspace().GetPlayers()
FortCharacter := Player.GetFortCharacter[]
do:
HUBTeleporter.Teleport(Player)
# Attendi un secondo per terminare il teletrasporto.
Sleep(1.0)
# Scongela il giocatore.
FortCharacter.ReleaseFromStasis()