Fai comparire e scomparire in modo alternato e veloce il personaggio di un giocatore quando subisce danni per ottenere un effetto di sfarfallio. SEO-Description: Fai comparire e scomparire in modo alternato e veloce il personaggio di un giocatore quando subisce danni per ottenere un effetto di sfarfallio. Parent: triad-infiltration-in-verse Order: 6 Type: tutorial Tags: Verse Tags: Multigiocatore Tags: Team Tags: Mappa Tags: Opzione Tags: Spazio di gioco Hero-image: BannerImage.png Topic-image: TopicImage.png Social-image: SocialMedia.png Prereq: triad-infiltration-5-making-players-invisible-in-verse
Per ottenere un effetto visivo di sfarfallio da applicare agli Infiltrati, dovrai nascondere e mostrare ripetutamente il personaggio di ogni giocatore. Devi fare in modo che ciò avvenga in una funzione ogni volta che un Infiltrato viene ferito, assicurandoti al contempo che il resto del codice continui a funzionare correttamente quando la funzione viene richiamata. La situazione si complica ulteriormente con la presenza di più Infiltrati. Dal momento che può capitare che più Infiltrati vengano feriti contemporaneamente durante un gioco, dovrai avere a disposizione un codice in grado di gestirli individualmente.
Per ottenere questo risultato, farai largo uso dell'espressione spawn. Generare una funzione ti permette di eseguirla in modo asincrono, evitando di sospendere il resto del codice. Creando una funzione per ogni Infiltrato, puoi fare in modo che lo sfarfallio di ogni infiltrato avvenga indipendentemente dagli altri.
Segui i passaggi seguenti per scoprire come applicare un effetto di sfarfallio a ogni personaggio di Infiltrato quando subisce danni.
Creare il loop per l'effetto di sfarfallio
- Aggiungi una nuova funzione
FlickerCharacter()
alla definizione della classeinvisibility_manager
. Questa funzione prende unfort_character
e gli applica un effetto di sfarfallio rendendolo alternativamente visibile e invisibile. Aggiungi lo specificatore<suspends>
a questa funzione per consentirne un'esecuzione asincrona.# Applica un effetto di sfarfallio alla visibilità di un agente, nascondendo e mostrando in modo ripetuto il suo fort_character FlickerCharacter(InCharacter:fort_character):void=<suspends> Logger.Print("FlickerCharacter() invocato")
- All'interno di
FlickerCharacter()
, esegui un loop diHide()
suInCharacter
,Sleep()
per un certo periodo di tempo (il valore diFlickerRateSeconds
che hai definito in precedenza),Show()
il personaggio e la funzioneSleep()
di nuovo. In questo modo sarà applicato un effetto di sfarfallio sul personaggio che permetterà ai giocatori nemici di seguirlo, ma con qualche difficoltà di mira a causa dei brevi periodi di visibilità.# Applica un effetto di sfarfallio alla visibilità di un agente, nascondendo e mostrando in modo ripetuto il suo fort_character FlickerCharacter(InCharacter:fort_character):void=<suspends> Logger.Print("FlickerCharacter() invocato") # Nascondi e mostra in loop il personaggio per creare un effetto di sfarfallio. loop: InCharacter.Hide() Sleep(FlickerRateSeconds) InCharacter.Show() Sleep(FlickerRateSeconds)
Interrompere il loop
Devi trovare un modo per interrompere questa funzione di loop quando il personaggio deve smettere di apparire e scomparire. La mappa
PlayerVisibilitySeconds
configurata in precedenza tiene traccia della quantità di tempo dell'effetto di sfarfallio, quindi dovrai ridurre questo tempo a ogni loop. Quando il tempo rimanente raggiunge lo 0, l'effetto di sfarfallio del giocatore dovrebbe smettere e potrai interrompere il loop. - Ottieni il tempo rimanente dell'effetto di sfarfallio accedendo alla mappa
PlayerVisibilitySeconds
utilizzandoInCharacter.GetAgent[]
come chiave e memorizzalo in una variabileTimeRemaining
. Puoi impostare il tempo rimanente nella mappa con la stessa espressione, diminuendo il valore diFlickerRateSeconds * 2
. In questo modo,TimeRemaining
diventerà il valore diPlayerVisibilitySeconds
dopo che l'espressioneset
è stata risolta. Tieni presente cheFlickerRateSeconds
deve essere moltiplicato per 2 dal momento che stai chiamandoSleep()
due volte per loop.# Applica un effetto di sfarfallio alla visibilità di un agente, nascondendo e mostrando in modo ripetuto il suo fort_character FlickerCharacter(InCharacter:fort_character):void=<suspends> Logger.Print("FlickerCharacter() invocato") # Nascondi e mostra in loop il personaggio per creare un effetto di sfarfallio. loop: InCharacter.Hide() Sleep(FlickerRateSeconds) InCharacter.Show() Sleep(FlickerRateSeconds) # Ad ogni loop, diminuisci la quantità di tempo in cui il personaggio sfarfalla di FlickerRateSeconds. # Se il tempo rimanente raggiunge lo 0, interrompi il loop. if: TimeRemaining := set PlayerVisibilitySeconds[InCharacter.GetAgent[]] -= FlickerRateSeconds * 2
- Controlla se
TimeRemaining
è minore o uguale a 0, il che indica che l'effetto di sfarfallio del personaggio dovrebbe interrompersi. Per farlo, chiamaHide()
sul personaggio per renderlo di nuovo invisibile e interrompi il loop. La tua funzioneFlickerCharacter()
dovrebbe essere simile alla seguente:# Applica un effetto di sfarfallio alla visibilità di un agente, nascondendo e mostrando in modo ripetuto il suo fort_character FlickerCharacter(InCharacter:fort_character):void=<suspends> Logger.Print("FlickerCharacter() invocato") # Nascondi e mostra in loop il personaggio per creare un effetto di sfarfallio. loop: InCharacter.Hide() Sleep(FlickerRateSeconds) InCharacter.Show() Sleep(FlickerRateSeconds) # Ad ogni loop, diminuisci la quantità di tempo in cui il personaggio sfarfalla di FlickerRateSeconds. # Se il tempo rimanente raggiunge lo 0, interrompi il loop. if: TimeRemaining := set PlayerVisibilitySeconds[InCharacter.GetAgent[]] -= FlickerRateSeconds * 2 TimeRemaining <= 0.0 then: InCharacter.Hide() break
Avviare e reimpostare l'effetto di sfarfallio
Considera cosa succede quando un Infiltrato con effetto di sfarfallio attivo viene ferito. In questo caso, l'introduzione di un'altra funzione FlickerCharacter()
potrebbe diventare rapidamente ingestibile, poiché ogni successiva istanza di danno genera un'altra funzione. Potresti quindi ritrovarti con decine di funzioni che agiscono sullo stesso personaggio. Al contrario, il valore del giocatore in PlayerVisibilitySeconds
deve essere azzerato ogni volta che subisce danni. Per farlo, definisci una funzione che verifichi se al giocatore è attualmente applicato l'effetto di sfarfallio. In caso affermativo, ripristina la durata dello sfarfallio. In caso contrario, genera un nuovo evento di sfarfallio per quel personaggio.
- Aggiungi una nuova funzione di aiuto
IsFlickering()
alla definizione della classeinvisibility_manager
, che utilizzerai per determinare se un giocatore è soggetto a sfarfallio. Questa funzione prende come argomento un agente e restituiscetrue
se il suo valore inPlayerVisibilitySeconds
è maggiore di0.0
. Aggiungi gli specificatoridecides
etransacts
a questa funzione sia per renderla fallibile che per poterla annullare in caso di errore.# Restituisce se c'è altro tempo per mostrare l'effetto sfarfallio del giocatore IsFlickering(InAgent:agent)<decides><transacts>:void= PlayerVisibilitySeconds[InAgent] > 0.0
- Aggiungi una nuova funzione
StartOrResetFlickering()
alla definizione della classeinvisibility_manager
. Questa funzione prende come argomento un agente e determina se per il giocatore deve essere applicato o annullato l'effetto di sfarfallio.# Avvia un nuovo evento di sfarfallio se l'agente era invisibile, altrimenti # ripristina l'effetto di sfarfallio attivo applicato all'agente. StartOrResetFlickering(InAgent:agent):void=
- In
StartOrResetFlickering()
, controlla che l'agente indicato non stia sfarfallando. In caso contrario, devi avviare un nuovo evento di sfarfallio per questo agente. Recupera ilfort_character
per tale agente e salvalo in una variabileFortCharacter
.# Avvia un nuovo evento di sfarfallio se l'agente era invisibile, altrimenti # ripristina l'effetto di sfarfallio attivo applicato all'agente. StartOrResetFlickering(InAgent:agent):void= if (not IsFlickering[InAgent], FortCharacter := InAgent.GetFortCharacter[]): Logger.Print("Tentativo di attivare un NUOVO FlickerEvent per questo personaggio")
- Imposta il valore dell'Agente in
PlayerVisibilitySeconds
suVulnerableSeconds
, quindispawn
una nuova funzioneFlickerCharacter()
per questo Agente, passando il relativoFortCharacter
.if (not IsFlickering[InAgent], FortCharacter := InAgent.GetFortCharacter[]): Logger.Print("Tentativo di attivare un NUOVO FlickerEvent per questo personaggio") # Inizio di un nuovo sfarfallio if (set PlayerVisibilitySeconds[InAgent] = VulnerableSeconds): spawn{FlickerCharacter(FortCharacter)} Logger.Print("FlickerEvent generato correttamente per questo personaggio")
- Se l'agente era già soggetto a sfarfallio, devi solo reimpostare il suo valore in
PlayerVisibilitySeconds
aVulnerableSeconds
. Ricorda che la precedente funzioneFlickerCharacter()
legge questo valore in modo asincrono. Di conseguenza, se il valore viene reimpostato mentreFlickerCharacter() è in loop, continua il loop senza interrompersi. La funzione
StartOrResetFlickering()` dovrebbe essere simile alla seguente:# Avvia un nuovo evento di sfarfallio se l'agente era invisibile, altrimenti # ripristina l'effetto di sfarfallio attivo applicato all'agente. StartOrResetFlickering(InAgent:agent):void= if (not IsFlickering[InAgent], FortCharacter := InAgent.GetFortCharacter[]): Logger.Print("Tentativo di attivare un NUOVO FlickerEvent per questo personaggio") # Inizio di un nuovo sfarfallio if (set PlayerVisibilitySeconds[InAgent] = VulnerableSeconds): spawn{FlickerCharacter(FortCharacter)} Logger.Print("FlickerEvent generato correttamente per questo personaggio") else: # Ripristina l'effetto di sfarfallio attivo if (set PlayerVisibilitySeconds[InAgent] = VulnerableSeconds): Logger.Print("Ripristina il FlickerTimer del personaggio a VulnerableSeconds")
Applicare l'effetto di sfarfallio agli Infiltrati danneggiati
Per collegare tutte queste funzioni tra loro, dovrai definire una funzione che gestisca cosa succede quando un Infiltrato subisce danni. Come nel caso di FlickerCharacter()
, devi controllare ogni Infiltrato individualmente per determinare se ha subito danni. A tal scopo, la funzione deve essere asincrona in modo da che sia possibile crearne una per ogni Infiltrato.
- Aggiungi una nuova funzione
OnInfiltratorDamaged()
alla definizione della classeinvisibility_manager
. Questa funzione prende un agente e gestisce la chiamata aStartOrResetFlickering()
quando l'agente subisce danni. Aggiungi lo specificatore<suspends>
a questa funzione per consentirne un'esecuzione asincrona.# Applica un effetto di sfarfallio alla visibilità di un agente ogni volta che subisce danni OnInfiltratorDamaged(InAgent:agent)<suspends>:void= Logger.Print("Tentativo di attivare l'effetto di sfarfallio per questo personaggio")
- Ottieni
fort_team_collection
per lo spazio di gioco attuale e memorizzala in una variabileTeamCollection
. Quindi ottieni ilfort_character
per l'agente passato a questa funzione.# Applica un effetto di sfarfallio alla visibilità di un agente ogni volta che subisce danni OnInfiltratorDamaged(InAgent:agent)<suspends>:void= Logger.Print("Tentativo di attivare l'effetto di sfarfallio per questo personaggio") TeamCollection := GetPlayspace().GetTeamCollection() if (FortCharacter := InAgent.GetFortCharacter[]):
- Poiché questa funzione deve monitorare continuamente l'agente che le viene passato, deve prevedere un loop. Il loop deve essere eseguito ogni volta che il personaggio indicato subisce danni e chiama
StartOrResetFlickering
sull'agente monitorato dalla funzione. Aggiungi un loop aOnInfiltratorDamaged
.# Applica un effetto di sfarfallio alla visibilità di un agente ogni volta che subisce danni OnInfiltratorDamaged(InAgent:agent)<suspends>:void= Logger.Print("Tentativo di attivare l'effetto di sfarfallio per questo personaggio") TeamCollection := GetPlayspace().GetTeamCollection() if (FortCharacter := InAgent.GetFortCharacter[]): loop:
- All'interno del loop, controlla se
IsVisibilityShared
è vero. In tal caso, significa che quando un Infiltrato subisce danni, a tutti gli Infiltrati del team deve essere applicato ugualmente un effetto di sfarfallio. Se questo parametro è abilitato, ottieni non solo il team di quell'agente, ma anche i giocatori che ne fanno parte rispettivamente tramite le chiamate aGetTeam[]
eGetAgents[]
.if (FortCharacter := InAgent.GetFortCharacter[]): loop: if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]):
- Ora, in un loop
for
, chiamaStartOrResetFlickering
su ogni compagno di team.if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]): # Per ogni compagno di team, imposta i secondi di PlayerVisibility e genera un FlickerEvent for(Teammate : TeamAgents): Logger.Print("Chiamata di StartOrResetFlickering su un compagno di team") StartOrResetFlickering(Teammate)
- Se la visibilità non è condivisa, chiama
StartOrResetFlickering
sull'agente monitorato da questa funzione.loop: if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]): # Per ogni compagno di team, imposta i secondi di PlayerVisibility e genera un FlickerEvent for(Teammate : TeamAgents): Logger.Print("Chiamata di StartOrResetFlickering su un compagno di team") StartOrResetFlickering(Teammate) else: # Applica l'effetto di sfarfallio solo al personaggio danneggiato Logger.Print("Chiamata di StartOrResetFlickering per InAgent") StartOrResetFlickering(InAgent)
- Infine, alla fine del loop, esegui
Await()
sull'eventoDamagedEvent()
del personaggio indicato. In questo modo il loop sarà eseguito solo quando un personaggio subisce danni. Tieni presente che questo loop verrà eseguito almeno una volta all'avvio della funzione, il che si traduce in almeno una chiamata aStartOrResetFlickering()
. Per questo motivo, gli Infiltrati iniziano il gioco con effetto di sfarfallio attivo e in seguito diventano invisibili. Questo serve a ricordare agli Infiltrati che sono invisibili, ma anche che la loro condizione di invisibilità non è permanente. La tua funzioneOnInfiltratorDamaged()
dovrebbe essere simile alla seguente:# Applica un effetto di sfarfallio alla visibilità di un agente ogni volta che subisce danni OnInfiltratorDamaged(InAgent:agent)<suspends>:void= Logger.Print("Tentativo di attivare l'effetto di sfarfallio per questo personaggio") TeamCollection := GetPlayspace().GetTeamCollection() if (FortCharacter := InAgent.GetFortCharacter[]): loop: if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]): # Per ogni compagno di team, imposta i secondi di PlayerVisibility e genera un FlickerEvent for(Teammate : TeamAgents): Logger.Print("Chiamata di StartOrResetFlickering su un compagno di team") StartOrResetFlickering(Teammate) else: # Applica l'effetto di sfarfallio solo al personaggio danneggiato Logger.Print("Chiamata di StartOrResetFlickering per InAgent") StartOrResetFlickering(InAgent) FortCharacter.DamagedEvent().Await()
Funzioni di generazione per i personaggi all'inizio del gioco
In StartInvisibilityManager()
, prima di chiamare Hide()
sul personaggio di un giocatore, genera una funzione OnInfiltratorDamaged()
per quel personaggio. In questo modo ogni Infiltrato avrà una funzione che lo monitora in modo asincrono e gestisce tutta la logica relativa al suo effetto di sfarfallio. La funzione StartInvisibilityManager()
dovrebbe essere simile alla seguente:
StartInvisibilityManager<public>(AllTeams:[]team, AllPlayers:[]player, Infiltrators:team):void=
Logger.Print("Script di invisibilità avviato!")
set Teams = GetPlayspace().GetTeamCollection().GetTeams()
for(PlayerSpawner:PlayersSpawners):
PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn)
# Per ogni giocatore, se si è generato nel team degli infiltrati, genera una funzione OnInfiltratorDamaged per quel
# giocatore. Poi rendi il loro personaggio invisibile.
for(TeamPlayer:AllPlayers):
if:
FortCharacter:fort_character = TeamPlayer.GetFortCharacter[]
CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]
Logger.Print("Team attuale del giocatore identificato")
Teams[0] = CurrentTeam
set PlayerVisibilitySeconds[TeamPlayer] = 0.0
Logger.Print("Giocatore aggiunto a PlayerVisibilitySeconds")
then:
spawn{OnInfiltratorDamaged(TeamPlayer)}
Logger.Print("Giocatore generato come infiltrato, rendendolo invisibile")
FortCharacter.Hide()
else:
Logger.Print("Questo giocatore non è un infiltrato")
Salva lo script, compilalo e fai clic su Avvia sessione nella barra degli strumenti UEFN per eseguire il playtest del livello. Quando esegui il test del tuo livello, ogni Infiltrato deve apparire con l'effetto di sfarfallio all'avvio dello script e in seguito diventare invisibile. Quando subiscono danni, ai giocatori deve essere applicato l'effetto di sfarfallio, sia individualmente che in team, a seconda delle impostazione di IsVisibilityShared
.

Passaggio successivo
Nel passaggio successivo di questo tutorial, imparerai come gestire i giocatori che si uniscono a una partita in corso.