Um den flackernden visuellen Effekt bei den Infiltratoren zu erzielen, muss die Spielfigur eines jeden Spielers wiederholt ein- und ausgeblendet werden. Dies soll in einer Funktion geschehen, wenn ein Infiltrator beschädigt wird, aber du musst auch sicherstellen, dass der Rest deines Codes weiterläuft, wenn diese Funktion aufgerufen wird. Noch komplizierter wird es in Situationen, in denen du mehrere Infiltratoren hast. Während eines Spiels können mehrere Infiltratoren gleichzeitig beschädigt werden, so dass du einen Code brauchst, der jeden von ihnen einzeln behandeln kann.
Um dies zu erreichen, wirst du den Ausdruck spawn ausgiebig nutzen. Wenn du eine Funktion spawnst, kannst du sie asynchron ausführen, ohne den Rest deines Codes zu unterbrechen. Indem du für jeden Infiltrator eine Funktion spawnen lässt, kannst du sicherstellen, dass das Flackern jedes Infiltrators unabhängig von den anderen geschieht.
Befolge diese Schritte, um zu lernen, wie du die Spielfiguren der Infiltratoren flackern lässt, wenn sie Schaden erleiden.
Erstellen der Flackerschleife
- Füge eine neue Funktion
FlickerCharacter()zur Definition der Klasseinvisibility_managerhinzu. Diese Funktion nimmt einenfort_characterund macht dessen Spielfigur abwechselnd sicht- und unsichtbar. Füge den<suspends>-Spezifizierer zu dieser Funktion hinzu, um sie asynchron laufen zu lassen.# Lässt die Sichtbarkeit eines Agents flackern, indem sein fort_character wiederholt ausgeblendet und angezeigt wird FlickerCharacter(InCharacter:fort_character)<suspends>:void= Logger.Print("FlickerCharacter() aufgerufen") - Schleife innerhalb von
FlickerCharacter(),Hide()auf demInCharacter, schlafe mitSleep()für eine bestimmte Zeit (dieFlickerRateSeconds, die du vorher definiert hast), zeige mitShow()die Spielfigur, und gehe zurück zuSleep(). Dadurch entsteht ein Flackereffekt auf der Spielfigur, der es gegnerischen Spielern ermöglicht, sie zu verfolgen, aber aufgrund der kurzen Phasen der Unsichtbarkeit einen Treffer schwierig macht.# Lässt die Sichtbarkeit eines Agents flackern, indem sein fort_character wiederholt ausgeblendet und angezeigt wird FlickerCharacter(InCharacter:fort_character)<suspends>:void= Logger.Print("FlickerCharacter() aufgerufen") # Der Charakter wird in einer Schleife ein- und ausgeblendet, um einen Flackereffekt zu erzeugen. loop: InCharacter.Hide() Sleep(FlickerRateSeconds) InCharacter.Show() Sleep(FlickerRateSeconds)Die Schleife durchbrechen
Du brauchst eine Möglichkeit, aus dieser Schleifenfunktion auszubrechen, wenn die Spielfigur aufhören soll zu flackern. Die Map
PlayerVisibilitySeconds, die du zuvor erstellt hast, verfolgt die Zeitspanne, die einem Spieler zum Flackern bleibt, also musst du diese Zeitspanne während jeder Schleife verringern. Wenn die verbleibende Zeit 0 erreicht, sollte der Spieler aufhören zu flackern, und du kannst die Schleife verlassen. - Hole die Zeit, die ein Spieler noch flackern kann, indem du auf die Map
PlayerVisibilitySecondszugreifst, wobei duInCharacter.GetAgent[]als Schlüssel verwendest und in einer VariablenTimeRemainingspeicherst. Du kannst die verbleibende Zeit in der Karte im selben Ausdruck festlegen, indem du den Wert umFlickerRateSeconds * 2verringerst. Auf diese Weise wirdTimeRemainingzum Wert inPlayerVisibilitySeconds, nachdem derset-Ausdruck aufgelöst wurde. Beachte, dassFlickerRateSecondsmit 2 multipliziert werden muss, da duSleep()zweimal pro Schleife aufrufst.# Lässt die Sichtbarkeit eines Agents flackern, indem sein fort_character wiederholt ausgeblendet und angezeigt wird FlickerCharacter(InCharacter:fort_character)<suspends>:void= Logger.Print("FlickerCharacter() aufgerufen") # Der Charakter wird in einer Schleife ein- und ausgeblendet, um einen Flackereffekt zu erzeugen. loop: InCharacter.Hide() Sleep(FlickerRateSeconds) InCharacter.Show() Sleep(FlickerRateSeconds) # In jeder Schleife wird die Zeit, in der der Charakter flackert, um FlickerRateSeconds verringert. # Wenn die verbleibende Zeit 0 ist, wird die Schleife verlassen. if: TimeRemaining := set PlayerVisibilitySeconds[InCharacter.GetAgent[]] -= FlickerRateSeconds * 2 - Prüfe, ob
TimeRemainingkleiner oder gleich 0 ist, was bedeutet, dass die Figur nicht mehr flackern sollte. Um dies zu tun, rufeHide()für das Zeichen auf, um es wieder unsichtbar zu machen, und verlasse die Schleife mitbreak. DeineFlickerCharacter()-Funktion sollte wie folgt aussehen:# Lässt die Sichtbarkeit eines Agents flackern, indem sein fort_character wiederholt ausgeblendet und angezeigt wird FlickerCharacter(InCharacter:fort_character)<suspends>:void= Logger.Print("FlickerCharacter() aufgerufen") # Der Charakter wird in einer Schleife ein- und ausgeblendet, um einen Flackereffekt zu erzeugen. loop: InCharacter.Hide() Sleep(FlickerRateSeconds) InCharacter.Show() Sleep(FlickerRateSeconds) # In jeder Schleife wird die Zeit, in der der Charakter flackert, um FlickerRateSeconds verringert. # Wenn die verbleibende Zeit 0 ist, wird die Schleife verlassen. if: TimeRemaining := set PlayerVisibilitySeconds[InCharacter.GetAgent[]] -= FlickerRateSeconds * 2 TimeRemaining <= 0.0 then: InCharacter.Hide() break
Flackern starten und zurücksetzen
Überlege, was passiert, wenn ein Infiltrator Schaden erleidet, während er bereits flackert. In diesem Fall könnte das Spawnen einer weiteren FlickerCharacter()-Funktion schnell aus dem Ruder laufen, da jede nachfolgende Instanz von Schaden eine weitere Funktion spawnen würde, und man könnte mit Dutzenden von Funktionen enden, die auf dieselbe Figur wirken. Stattdessen muss der Wert des Spielers in PlayerVisibilitySeconds zurückgesetzt werden, wenn er Schaden nimmt. Zu diesem Zweck definierst du eine Funktion, die prüft, ob ein Spieler flackert. Wenn dies der Fall ist, muss die Dauer des Flackerns neu eingestellt werden. Wenn nicht, wird ein neues Flacker-Event für diese Figur erzeugt.
- Füge eine neue Hilfsfunktion
IsFlickering()zur Klassendefinitioninvisibility_managerhinzu, mit der du feststellen kannst, ob ein Spieler flackert. Diese Funktion nimmt einen Agenten als Argument und gibttruezurück, wenn sein Wert inPlayerVisibilitySecondsgrößer als0.0ist. Füge die Spezifiziererdecidesundtransactszu dieser Funktion hinzu, damit sie sowohl fehlschlagen als auch im Falle eines Fehlers zurückgesetzt werden kann.# Gibt zurück, ob der Spieler noch Zeit zum Flackern hat. IsFlickering(InAgent:agent)<decides><transacts>:void= PlayerVisibilitySeconds[InAgent] > 0.0 - Füge eine neue Funktion
StartOrResetFlickering()zur Definition der Klasseinvisibility_managerhinzu. Diese Funktion nimmt einen Agenten als Argument und bestimmt, ob das Flackern eines Spielers starten oder zurücksetzen soll.# Startet ein neues Flacker-Event, wenn der Agent unsichtbar war, andernfalls # wird das laufende Flackern des Agenten zurückgesetzt. StartOrResetFlickering(InAgent:agent):void= - Prüfe in
StartOrResetFlickering(), ob der angegebene Agent nicht flackert. Wenn nicht, musst du ein neues Flacker-Event für diesen Agenten starten. Hole denfort_characterfür diesen Agenten und speichere ihn in einer VariablenFortCharacter.# Startet ein neues Flacker-Event, wenn der Agent unsichtbar war, andernfalls # wird das laufende Flackern des Agenten zurückgesetzt. StartOrResetFlickering(InAgent:agent):void= if (not IsFlickering[InAgent], FortCharacter := InAgent.GetFortCharacter[]): Logger.Print("Versuch, ein NEUES FlickerEvent für diesen Charakter zu starten") - Setze den Wert des Agenten in
PlayerVisibilitySecondsaufVulnerableSeconds, dann spawne mitspawneine neueFlickerCharacter()-Funktion für diesen Agenten, die dessenFortCharacterübergibt.if (not IsFlickering[InAgent], FortCharacter := InAgent.GetFortCharacter[]): Logger.Print("Versuch, ein NEUES FlickerEvent für diesen Charakter zu starten") # Neues Flackern gestartet if (set PlayerVisibilitySeconds[InAgent] = VulnerableSeconds): spawn{FlickerCharacter(FortCharacter)} Logger.Print("FlickerEvent für diesen Charakter gespawnt") - Wenn der Agent bereits flackerte, musst du nur seinen Wert in
PlayerVisibilitySecondsaufVulnerableSecondszurücksetzen. Denke daran, dass die FunktionFlickerCharacter()diesen Wert asynchron ausliest. Wenn also der Wert zurückgesetzt wird, währendFlickerCharacter()eine Schleife durchläuft, wird die Schleife ohnebreak-Unterbrechung fortgesetzt. DeineStartOrResetFlickering()-Funktion sollte wie folgt aussehen:# Startet ein neues Flacker-Event, wenn der Agent unsichtbar war, andernfalls # wird das laufende Flackern des Agenten zurückgesetzt. StartOrResetFlickering(InAgent:agent):void= if (not IsFlickering[InAgent], FortCharacter := InAgent.GetFortCharacter[]): Logger.Print("Versuch, ein NEUES FlickerEvent für diesen Charakter zu starten") # Neues Flackern gestartet if (set PlayerVisibilitySeconds[InAgent] = VulnerableSeconds): spawn{FlickerCharacter(FortCharacter)} Logger.Print("FlickerEvent für diesen Charakter gespawnt") else: # Laufendes Flackern zurücksetzen if (set PlayerVisibilitySeconds[InAgent] = VulnerableSeconds): Logger.Print("FlickerTimer des Charakters auf VulnerableSeconds zurückgesetzt")
Infiltratoren bei Beschädigung flackern lassen
Um all diese Funktionen miteinander zu verbinden, wirst du eine Funktion definieren, die sich darum kümmert, was passiert, wenn ein Infiltrator beschädigt wird. Genau wie bei FlickerCharacter() musst du jeden Infiltrator einzeln verfolgen, um festzustellen, ob er beschädigt wurde. Die Funktion dafür muss asynchron sein, damit du eine für jeden Infiltrator spawnen kannst.
- Füge eine neue Funktion
OnInfiltratorDamaged()zur Definition der Klasseinvisibility_managerhinzu. Diese Funktion nimmt einen Agenten und handhabt den Aufruf vonStartOrResetFlickering(), wenn der Agent beschädigt ist. Füge den<suspends>-Spezifizierer zu dieser Funktion hinzu, um sie asynchron laufen zu lassen.# Die Sichtbarkeit eines Agents flackert, wenn er Schaden erleidet OnInfiltratorDamaged(InAgent:agent)<suspends>:void= Logger.Print("Versuch, diesen Charakter flackern zu lassen") - Hole die
fort_team_collectionfür den aktuellen Spielraum und speichere sie in einer VariablenTeamCollection. Hole dann dasfort_characterfür den Agenten, der an diese Funktion übergeben wurde.# Die Sichtbarkeit eines Agents flackert, wenn er Schaden erleidet OnInfiltratorDamaged(InAgent:agent)<suspends>:void= Logger.Print("Versuch, diesen Charakter flackern zu lassen") TeamCollection := GetPlayspace().GetTeamCollection() if (FortCharacter := InAgent.GetFortCharacter[]): - Da diese Funktion den ihr übergebenen Agenten ständig überwachen muss, ist eine Schleife erforderlich. Diese Schleife sollte jedes Mal ablaufen, wenn die angegebene Figur beschädigt wird und ruft
StartOrResetFlickeringauf dem Agenten auf, den die Funktion überwacht. Füge eine Schleife zuOnInfiltratorDamagedhinzu.# Die Sichtbarkeit eines Agents flackert, wenn er Schaden erleidet OnInfiltratorDamaged(InAgent:agent)<suspends>:void= Logger.Print("Versuch, diesen Charakter flackern zu lassen") TeamCollection := GetPlayspace().GetTeamCollection() if (FortCharacter := InAgent.GetFortCharacter[]): loop: - Prüfe innerhalb der Schleife, ob
IsVisibilitySharedtrue ist. Wenn dies der Fall ist, bedeutet dies, dass alle Infiltratoren im Team zu flackern beginnen sollten, wenn ein Infiltrator beschädigt wird. Wenn diese Einstellung aktiviert ist, werden sowohl das Team für diesen Agenten als auch die Spieler in diesem Team durch Aufrufe vonGetTeam[]bzw.GetAgents[]ermittelt.if (FortCharacter := InAgent.GetFortCharacter[]): loop: if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]): - Rufe nun in einer
for-SchleifeStartOrResetFlickeringfür jedes Teammitglied auf.if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]): # Setzt sie für jedes Teammitglied in PlayerVisibility Sekunden und spawnt ein FlickerEvent for(Teammate:TeamAgents): Logger.Print("Aufruf von StartOrResetFlickering bei einem Teammitglied") StartOrResetFlickering(Teammate)Ein Wenn die Sichtbarkeit nicht gemeinsam genutzt wird, dann rufe
StartOrResetFlickeringauf dem Agenten auf, den diese Funktion überwacht.loop: if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]): # Setzt sie für jedes Teammitglied in PlayerVisibility Sekunden und spawnt ein FlickerEvent for(Teammate:TeamAgents): Logger.Print("Aufruf von StartOrResetFlickering bei einem Teammitglied") StartOrResetFlickering(Teammate) else: # Lässt nur den beschädigten Charakter flackern Logger.Print("Aufruf von StartOrResetFlickering auf InAgent") StartOrResetFlickering(InAgent) - Schließlich, am Ende der Schleife, warte mit
Await()auf dasDamagedEvent()der Figur. Auf diese Weise wird die Schleife nur durchlaufen, wenn eine Figur Schaden genommen hat. Beachte, dass diese Schleife mindestens einmal ausgeführt wird, wenn die Funktion startet, was mindestens einen Aufruf vonStartOrResetFlickering()bedeutet. Aus diesem Grund beginnen die Infiltratoren das Spiel flackernd und werden dann unsichtbar. Dies hilft, die Infiltratoren daran zu erinnern, dass sie unsichtbar sind, aber auch daran, dass Unsichtbarkeit nicht dauerhaft ist. DeineOnInfiltratorDamaged()-Funktion sollte wie folgt aussehen:# Die Sichtbarkeit eines Agents flackert, wenn er Schaden erleidet OnInfiltratorDamaged(InAgent:agent)<suspends>:void= Logger.Print("Versuch, diesen Charakter flackern zu lassen") TeamCollection := GetPlayspace().GetTeamCollection() if (FortCharacter := InAgent.GetFortCharacter[]): loop: if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]): # Setzt sie für jedes Teammitglied in PlayerVisibility Sekunden und spawnt ein FlickerEvent for(Teammate:TeamAgents): Logger.Print("Aufruf von StartOrResetFlickering bei einem Teammitglied") StartOrResetFlickering(Teammate) else: # Lässt nur den beschädigten Charakter flackern Logger.Print("Aufruf von StartOrResetFlickering auf InAgent") StartOrResetFlickering(InAgent) FortCharacter.DamagedEvent().Await()
Funktionen für Figuren beim Spielstart spawnen
Spawne zurück in StartInvisibilityManager(), vor dem Aufruf von Hide() für eine Spielerfigur, eine OnInfiltratorDamaged() Funktion für diese Figur. Auf diese Weise hat jeder Infiltrator eine Funktion, die ihn asynchron überwacht und alle Logik im Zusammenhang mit seinem Flackern behandelt. StartInvisibilityManager() sollte folgendermaßen aussehen:
StartInvisibilityManager<public>(AllTeams:[]team, AllPlayers:[]player, Infiltrators:team):void=
Logger.Print("Unsichtbarkeitsscript gestartet!")
set Teams = GetPlayspace().GetTeamCollection().GetTeams()
for(PlayerSpawner:PlayersSpawners):
PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn)
# Für jeden Spieler, wenn er im Infiltrator-Team gespawnt ist, wird eine OnInfiltratorDamaged-Funktion für diesen
# Spieler gespawnt. Mache dann seinen Charakter unsichtbar.
for(TeamPlayer:AllPlayers):
if:
FortCharacter:fort_character = TeamPlayer.GetFortCharacter[]
CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]
Logger.Print("Aktuelles Team des Spielers abgerufen")
Teams[0] = CurrentTeam
set PlayerVisibilitySeconds[TeamPlayer] = 0.0
Logger.Print("Spieler hinzugefügt zu PlayerVisibilitySeconds")
then:
spawn{OnInfiltratorDamaged(TeamPlayer)}
Logger.Print("Spieler wurde als Infiltrator gespawnt, er wird unsichtbar gemacht")
FortCharacter.Hide()
else:
Logger.Print("Dieser Spieler ist kein Infiltrator)")
Speichere das Script, erstelle es und klicke auf Sitzung starten in der UEFN-Symbolleiste, um das Level zu testen. Wenn du dein Level testest, sollte jeder Infiltrator flackern, wenn das Script startet, und dann unsichtbar werden. Wenn sie Schaden erleiden, sollten sie flackern, entweder einzeln oder als Team, je nachdem, was du unter IsVisibilityShared eingestellt hast.

Nächster Schritt
Im nächsten Schritt dieses Tutorials lernst du, wie du Spieler handhabst, die dem laufenden Spiel beitreten.