Die Unsichtbarkeit des Infiltrators schafft ein interessantes Problem, wenn es darum geht, den Zielgegenstand des Verteidigers zu ergreifen. Wie sollen die Verteidiger einen unsichtbaren Spieler finden, der mit seinem Zielgegenstand zurück zur Basis sprinten könnte? Um dieses Problem zu lösen, kannst du eine visuelle Hilfe, in diesem Fall ein Prop, verwenden, um den Verteidigern zu zeigen, wo sich der Infiltrator befindet.
Befolge die folgenden Schritte, um zu lernen, wie du ein Objekt erstellst, das über dem Kopf eines Spielers schwebt, wenn dieser ein Objektiv in der Hand hält.
Erstellen des Gegenstandsgreifmanagers
- Erstelle mit dem Verse-Explorer ein neues Verse-Gerät mit dem Namen item_capture_manager und ziehe das Gerät in das Level.
- Am Anfang der Datei
item_capture_manager:- Füge
using { /UnrealEngine.com/Temporary/SpatialMath }hinzu, um auf die Strukturvector3zuzugreifen. Damit weißt du, wohin du die Indikatoren teleportieren musst, die über dem Kopf des Spielers schweben. Füge auchusing { /Fortnite.com/Characters }hinzu, um auf denfort_charactereines Spielers zuzugreifen.using { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /Fortnite.com/Characters } using { /UnrealEngine.com/Temporary/Diagnostics } using { /UnrealEngine.com/Temporary/SpatialMath }
- Füge
- Füge in der Klassendefinition von
item_capture_managerdie folgenden Felder hinzu:- Ein bearbeitbares Array von Eroberungsgegenstands-Spawnpunkt-Geräten mit dem Namen
CaptureItemSpawners. Dieses Array enthält das Eroberungsgegenstands-Spawnpunkt-Gerät für die Infiltratoren.item_capture_manager := class(creative_device): Logger:log = log{Channel := triad_item_capture_log_channel} # Gegenstands-Spawnpunkt erfassen, der den zu erobernden Gegenstand spawnt. @editable CaptureItemSpawner:capture_item_spawner_device = capture_item_spawner_device{} - Ein bearbeitbares Kreativmodus-Prop namens
CaptureItemIndicator. Dies ist das Prop, das über dem Kopf eines Infiltrators schwebt, wenn er das Ziel ergreift.# Gegenstands-Spawnpunkt erfassen, der den zu erobernden Gegenstand spawnt. @editable CaptureItemSpawner:capture_item_spawner_device = capture_item_spawner_device{} # Prop, das über dem Kopf eines Spielers schwebt, wenn dieser den Gegenstand des # CaptureItemSpawner hält @editable CaptureItemIndicator:creative_prop = creative_prop{} - Ein editierbarer Kartenindikator mit dem Namen
MapIndicator. Dieser befindet sich unter dem CaptureItemSpawner im Level und zeigt auf der Karte an, wo die Ziele für jedes Team liegen.# Prop, das über dem Kopf eines Spielers schwebt, wenn dieser den Gegenstand des # CaptureItemSpawner hält @editable CaptureItemIndicator:creative_prop = creative_prop{} # Indikator, der auf der Karte anzeigt, wo sich die Ziele für jedes Team befinden. @editable MapIndicator:map_indicator_device = map_indicator_device{} - Zwei bearbeitbare Floats
UpdateRateSecondsundVerticalOffset. Die erste steuert, wie schnell sich die Position desCaptureItemIndicatorändert, und die zweite steuert, wie weit über dem Kopf eines Spielers derCaptureItemIndicatorschwebt.# Indikator, der auf der Karte anzeigt, wo sich die Ziele für jedes Team befinden. @editable MapIndicator:map_indicator_device = map_indicator_device{} # Wie oft der CaptureItemIndicator seine Position aktualisiert. @editable UpdateRateSeconds:float = 0.15 # Wie hoch über dem Kopf eines Spielers der CaptureItemIndicator schwebt. @editable VerticalOffset:float = 180.0 - Ein editierbarer HUD-Nachrichtenübermittler mit dem Namen
ItemGrabbedMessageDeviceDieser sendet eine Nachricht an jeden Spieler, wenn ein Ziel aufgenommen wird.# Wie hoch über dem Kopf eines Spielers der CaptureItemIndicator schwebt. @editable VerticalOffset:float = 180.0 # Zeigt eine Nachricht an, wenn ein Spieler den Eroberungsgegenstand holt @editable ItemGrabbedMessageDevice:hud_message_device = hud_message_device{} - Ein editierbares Punkteanpassungs-Gerät mit dem Namen
ScoreManagerDevice. Dadurch erhält ein Team immer dann Punkte, wenn ein Spieler das Objekt erobert.# Zeigt eine Nachricht an, wenn ein Spieler den Eroberungsgegenstand holt @editable ItemGrabbedMessageDevice:hud_message_device = hud_message_device{} # Vergibt Punkte, wenn ein Spieler den Eroberungsgegenstand erobert. @editable ScoreManagerDevice:score_manager_device = score_manager_device{} - Ein editierbarer Float mit dem Namen
ReturnTime. Wenn der Eroberungsgegenstand eine Rückgabezeit hat, bevor er zum CaptureItemSpawner zurückkehrt, musst du verfolgen, wie lange die Dauer dieser Rückgabezeit ist, um zu wissen, wann die Indikatoren zum CaptureItemSpawner zurückkehren.
- Ein bearbeitbares Array von Eroberungsgegenstands-Spawnpunkt-Geräten mit dem Namen
- Hinzufügen einer neuen Methode
FollowCharacter()zur Definition der Klasseitem_capture_manager. Diese Methode nimmt einenfort_characterund verfolgt ihn mit Hilfe von Indikatoren, die über seinem Kopf schweben. Füge den<suspends>-Bezeichner zu dieser Funktion hinzu, da du einen von diesen für einen Spieler spawnen willst, wenn er ein Ziel hält.# Bewirkt, dass der CaptureItemIndicator einem Spieler kontinuierlich über seinem Kopf folgt. # Wechselt zwischen der Aktualisierungsschleife für den CaptureItemIndictator und der Frage, ob der Spieler # den Gegenstand fängt, fallen lässt oder eliminiert wird. FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("FollowCharacter-Funktion gespawnt")
Ein Rennen laufen und dabei das Ziel im Auge behalten
Du musst überlegen, was passiert, wenn ein Spieler das Ziel ergreift. Der Spieler kann:
- Sich bewegen. In diesem Fall müssen die CaptureItem- und Kartenindikatoren ständig mit der Position des Spielers aktualisiert werden. Dies kann in einer Schleife erfolgen.
- Das Ziel erobern. In diesem Fall müssen die Indikatoren irgendwo außer Sichtweite zum CaptureItemSpawner zurückkehren, da sie nur sichtbar sein sollten, wenn ein Spieler den Gegenstand in der Hand hält.
- Das Ziel fallen lassen oder eliminiert werden. In diesem Fall müssen die Indikatoren dort bleiben, wo der Gegenstand abgelegt wurde, und zum CaptureItemSpawner zurückkehren, wenn der erfasste Gegenstand zurückkehrt.
Dazu wirst du einen Rennen-Ausdruck einrichten. Durch die Verwendung eines race zwischen den drei oben genannten Bedingungen kannst du die Position des Indikators weiter aktualisieren, während du darauf wartest, dass der Spieler das Ziel entweder fallen lässt oder erobert.
- Füge einen
race-Ausdruck zuFollowCharacter()hinzu. Richte das Rennen so ein, dass es zwischen einemloop, einemAwait()für dasItemCapturedEventdesCaptureItemSpawner, einemAwait()für dasItemCapturedDroppedEventdesCaptureItemSpawnerund einemAwait()für dasEliminatedEvent()desFortCharacterläuft.FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("FollowCharacter-Funktion gespawnt") race: loop: CaptureItemSpawner.ItemCapturedEvent.Await() CaptureItemSpawner.ItemDroppedEvent.Await() FortCharacter.EliminatedEvent().Await() - Ermittle im
loopdie Position vonFortCharacterund speichere sie in der VariablenTransform.loop: Transform := FortCharacter.GetTransform() - Spawne nun ein
MoveTo(), um sowohlCaptureItemIndicatorals auchMapIndicatorentsprechend der Verschiebung und Rotation desTransformplus demVerticalOffset, den du zuvor festgelegt hast, über eine Zeitspanne vonUpdateRateSecondszu bewegen. Du möchtest einenSpawn{}für beideMoveTo()-Funktionen durchführen, da sowohlCaptureItemIndicatorals auchMapIndicatorgenau zur gleichen Zeit verschoben werden müssen, anstatt darauf zu warten, dass der Ausdruck des jeweils anderen abgeschlossen ist. Da die Verschiebung einvector3ist, der ausX,YundZKoordinaten besteht, musst du denVerticalOffsetin einen neuenvector3einfügen. DaVerticalOffsetder vertikale Abstand über dem Kopf eines Spielers ist, setze ihn alsZ-Wert desvector3.loop: Transform := FortCharacter.GetTransform() spawn{CaptureItemIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)} spawn{MapIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)} - Zum Schluss
0,0Sekunden schlafen. Dadurch wird sichergestellt, dass die Schleife nur einmal pro Simulationsaktualisierung ausgeführt wird und nicht außer Kontrolle gerät undMoveTo()-Funktionen erzeugt. DeinFollowCharacter()-Code sollte nun wie folgt aussehen:# Bewirkt, dass der CaptureItemIndicator einem Spieler kontinuierlich über seinem Kopf folgt. # Wechselt zwischen der Aktualisierungsschleife für den CaptureItemIndictator und der Frage, ob der Spieler # den Gegenstand fängt, fallen lässt oder eliminiert wird. FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("FollowCharacter-Funktion gespawnt") race: loop: Transform := FortCharacter.GetTransform() spawn{CaptureItemIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)} spawn{MapIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)} # Wir möchten sicherstellen, dass diese Schleife nur einmal pro Simulationsaktualisierung ausgeführt wird, also schlafen wir für einen Spieltick. Sleep(0.0) CaptureItemSpawner.ItemCapturedEvent.Await() CaptureItemSpawner.ItemDroppedEvent.Await() FortCharacter.EliminatedEvent().Await() Logger.Print("Ziel fallengelassen oder erobert")Zurücksetzen der Indikatoren
- Wenn der Eroberungsgegenstand erobert oder zurückgegeben wird, müssen die Indikatoren an den
CaptureItemSpawnerzurückgegeben werden, und zwar irgendwo außer Sichtweite. In diesem Fall teleportierst du sie hoch über demCaptureItemSpawner. Füge dazu eine Funktion namensReturnIndicators()zur Klassendefinitionitem_capture_managerhinzu.# Setzt die Karten- und Eroberungsgegenstand-Indikatoren wieder an ihre ursprüngliche Position über den Spawnpunkten zurück. ReturnIndicators(InAgent:agent):void= - Hole die Transformierung von
CaptureItemSpawnerund speichere sie in der VariablenSpawnerTransform. Spawne dann einMoveTo()für denCaptureItemIndicatorund denMapIndicatormit der Transformation und Rotation desCaptureItemSpawnerund füge denVerticalOffsetauf die gleiche Weise hinzu, wie du es imloopgetan hast, um sie über denCaptuerItemSpawnwerzu setzen. Wenn du willst, dass dein Prop weit außer Sichtweite bleibt, kannst du denVerticalOffsetmit einer größeren Zahl, in diesem Fall 10, multiplizieren. Deine fertigeReturnIndicators()-Methode sollte wie folgt aussehen:# Setzt die Karten- und Eroberungsgegenstand-Indikatoren wieder an ihre ursprüngliche Position über den Spawnpunkten zurück. ReturnIndicators():void= SpawnerTransform := CaptureItemSpawner.GetTransform() # Teleportiere dich zurück zum Spawner und verstecke den CaptureItemIndicator und den MapIndicator über der Karte außerhalb der Site. spawn{CaptureItemIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)} spawn{MapIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)} Logger.Print("Indikatoren zurück an Eroberungs-Spawner gegeben")
Umgang mit Spielern, die das Ziel schnappen, fallen lassen und erobern.
- Füge eine neue Methode
OnItemPickedUp()zur Definition der Klasseitem_capture_managerhinzu. Diese Methode nimmt einenagentund erzeugt eine Instanz vonFollowCharacter()für diesen Charakter.# Signalisiere jedem Spieler, wenn ein Spieler das Ziel holt OnItemPickedUp(InAgent:agent):void= Logger.Print("Ziel geholt!") - Hole das
FortCharacterfürInAgent, und erzeuge eineFollowCharacter()-Funktion mit diesemFortCharacter. Deine fertigeOnItemPickedUp()-Methode sollte wie folgt aussehen:# Signalisiere jedem Spieler, wenn ein Spieler das Ziel holt OnItemPickedUp(InAgent:agent):void= Logger.Print("Ziel geholt!") if(FortCharacter := InAgent.GetFortCharacter[]): ItemGrabbedMessageDevice.Show() spawn{FollowCharacter(FortCharacter)} - Füge eine neue Methode
OnItemCaptured()zur Definition der Klasseitem_capture_managerhinzu. Diese Methode nimmt denagent, der das Ziel erobert hat.# Wenn der Gegenstand erbeutet wurde, erhält das erobernde Team Punkte und gibt die Indikatoren zurück. OnItemCaptured(CapturingAgent:agent):void= Logger.Print("Ziel erobert!") - Aktiviere in
OnItemCaptured()dasScoreManagerDevice, um den Team-Punktestand des erobernden Spielers zu vergeben, und rufeReturnIndicators()auf, um die Indikatoren zurückzugeben.# Wenn der Gegenstand erbeutet wurde, erhält das erobernde Team Punkte und gibt die Indikatoren zurück. OnItemCaptured(CapturingAgent:agent):void= Logger.Print("Ziel erobert!") ScoreManagerDevice.Activate() ReturnIndicators() - Füge eine neue Methode
OnItemDropped()zur Definition der Klasseitem_capture_managerhinzu. Diese Methode nimmt denAgent, der den Gegenstand fallengelassen hat.# Wenn ein Spieler einen Gegenstand fallen lässt, wird eine WaitForReturn()-Funktion erzeugt, # wenn ReturnTime größer als 0 ist. OnItemDropped(InAgent:agent):void= Logger.Print("Ziel fallengelassen!") - Wenn das Ziel fallen gelassen wird, sollten die Indikatoren in der Nähe des Ziels verbleiben, bis das Ziel entweder aufgenommen wird oder zum
CaptureItemSpawnerzurückkehrt. Um zu wissen, wann die Indikatoren zurückgegeben werden sollen, verwendest du die VariableReturnTime, die du zuvor eingerichtet hast. WennReturnTimegrößer als oder gleich0,0ist, möchtest du diese Zeitspanne abwarten und dann die Indikatoren zurückgeben. WennReturnTimenegativ ist, hat das Ziel keine Rückgabezeit, sodass du die Indikatoren nicht zurückgeben musst. Um die Indikatoren zurückzugeben, spawnst du eine neue Hilfsfunktion mit dem NamenWaitForReturn(), die du im nächsten Schritt definierst.# Wenn ein Spieler einen Gegenstand fallen lässt, wird eine WaitForReturn()-Funktion erzeugt, # wenn ReturnTime größer als 0 ist. OnItemDropped(InAgent:agent):void= Logger.Print("Ziel fallengelassen!") if(ReturnTime >= 0.0): spawn{WaitForReturn()} else: Logger.Print("Das fallengelassene Ziel kehrt nicht zurück") - Füge eine neue Methode
WaitForReturn()zur Definition der Klasseitem_capture_managerhinzu. Diese Funktion wartet eine Zeitspanne vonReturnTimeund gibt dann den Wert zurück, wenn das Ziel nicht aufgehoben wurde, bevor die Wartezeit abgelaufen ist. Füge den<suspends>-Modifikator zu dieser Methode hinzu, damit sieSleep()ausführen kann.# Wartet eine ReturnTime-Zeitspanne und gibt dann die Indikatoren zurück. WaitForReturn()<suspends>:void= Logger.Print("Warten, um die Indikatoren zurückzugeben …") - Ob du die Indikatoren zurückgeben musst oder nicht, hängt davon ab, ob das Ziel vor Ablauf der
ReturnTimeaufgehoben wurde. Wenn dies der Fall war, solltest du die Indikatoren nicht zurückgeben, da sie sofort zum Spieler zurückspringen würden, was zu seltsamen visuellen Effekten führen könnte. Um dieses Problem zu lösen, verwendest du eine Logikvariable, deren Wert gleich dem Ergebnis eines Rennens ist.# Wartet eine ReturnTime-Zeitspanne und gibt dann die Indikatoren zurück. WaitForReturn()<suspends>:void= Logger.Print("Warten, um die Indikatoren zurückzugeben …") # Gibt das CaptureItem und die Map-Indikator zurück, wenn der Eroberungsgegenstand # nicht aufgehoben wird, bevor die Zeit abläuft. ShouldReturn:logic := race: - Deine Funktion
WaitForReturn()muss zwischen zwei Bedingungen wechseln. DieReturnTimeläuft ab und das Ziel kehrt zumCaptureItemSpawnerzurück. In diesem Fall musst du die Indikatoren zurückgeben undShouldReturnsolltetruesein. Oder das Ziel wird vor Ablauf vonReturnTimeaufgehoben, in diesem Fall sollteShouldReturnfalsesein. Da jede dieser Bedingungen einen Wert zurückgibt, wirst du das Rennen mit zwei getrennten [blocks] (Block-in-Verse) durchführen.ShouldReturn:logic := race: block: block: - Im ersten Block rufst du
Sleep()für eine Zeitspanne vonReturnTimeauf und gibst danntruezurück. Im zweiten Block,Await()dasCaptureItemSpawner.ItemPickedUpEvent, und gib False zurück. Die VariableShouldReturnwird nun mit dem Wert initialisiert, der als erstes erreicht wird.ShouldReturn:logic := race: block: Sleep(ReturnTime) true block: CaptureItemSpawner.ItemPickedUpEvent.Await() false - Wenn
ShouldReturnTrue ist, musst du die Indikatoren zurückgeben. RufeReturnIndicators()auf, wennShouldReturnauftrueausgewertet wird. Dein fertiggestellterWaitForReturn()-Code sollte nun so aussehen:# Wartet eine ReturnTime-Zeitspanne und gibt dann die Indikatoren zurück. WaitForReturn()<suspends>:void= Logger.Print("Warten, um die Indikatoren zurückzugeben …") # Gibt das CaptureItem und die Map-Indikator zurück, wenn der Eroberungsgegenstand # nicht aufgehoben wird, bevor die Zeit abläuft. ShouldReturn:logic := race: block: Sleep(ReturnTime) true block: CaptureItemSpawner.ItemPickedUpEvent.Await() false if(ShouldReturn?): ReturnIndicators() - Abonniere jetzt in
OnBegin()dasItemPickedUpEventdesCaptureItemSpawneraufOnItemPickedUp(), dasItemCapturedEventaufOnItemCaptured()und dasItemDroppedEventaufOnItemDropped().OnBegin<override>()<suspends>:void= CaptureItemSpawner.ItemPickedUpEvent.Subscribe(OnItemPickedUp) CaptureItemSpawner.ItemCapturedEvent.Subscribe(OnItemCaptured) CaptureItemSpawner.ItemDroppedEvent.Subscribe(OnItemDropped) SpawnerTransform := CaptureItemSpawner.GetTransform() - Schließlich setzt du in
OnBegin()die Indikatoren in ihre Ausgangspositionen, wenn das Skript läuft, indem duMoveTo()fürCaptureItemIndicatorundMapIndicatoraufrufst. DeinOnBegin()-Code sollte jetzt wie der folgende Code aussehen:OnBegin<override>()<suspends>:void= CaptureItemSpawner.ItemPickedUpEvent.Subscribe(OnItemPickedUp) CaptureItemSpawner.ItemCapturedEvent.Subscribe(OnItemCaptured) CaptureItemSpawner.ItemDroppedEvent.Subscribe(OnItemDropped) SpawnerTransform := CaptureItemSpawner.GetTransform() # Teleportiere dich zurück zum Spawner und verstecke den CaptureItemIndicator unter der Karte außerhalb des Standorts. CaptureItemIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds) MapIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds) -
Zurück im Editor speichere das Script, erstelle es und ziehe das Gerät in das Level. Wähle ein geeignetes Prop, das als
CaptureItemIndicatorin dein Level dienen soll. Das kann alles sein, solange es gut sichtbar ist. In diesem Beispiel verwenden wir einen Diamanten. Weise im Details-Panel CaptureItemSpawner dem InfiltratorCaptureSpawner und CaptureItemIndicator dem gewählten Prop zu. Weise außerdem MapIndicator dem Kartenindikator des Infiltrators, ItemGrabbedMessageDevice dem HUD-Nachrichtengerät des Infiltrators und ScoreManagerDevice dem Punktemanager des Infiltrators zu. Setze ReturnTime auf eine negative Zahl, wenn der Gegenstand des Infiltrators nicht zurückkehrt.Du solltest auch eine Instanz von
item_capture_managerfür die Angreifer einrichten. Denke daran, den CaptureItemIndicator auf ein anderes Prop als die Infiltrator-Props zu setzen, um visuelle Verwirrung bei den Teams zu vermeiden, und stelle sicher, dass alle anderen Geräte zugewiesen werden. Setze ReturnTime auf eine positive Zahl, da der Eroberungsgegenstand des Angreifers nach einer bestimmten Zeit zurückkehrt. - Klicke auf Sitzung starten in der UEFN-Symbolleiste, um das Level zu testen. Wenn du dein Level testest, sollte ein Spieler ein Prop über seinem Kopf haben, wenn er ein Ziel ergreift. Das Prop sollte sich mit dem Spieler bewegen, und wenn er das Ziel fallen lässt oder einnimmt, sollte sich das Prop zurück zum Eroberungsgegenstands-Spawnpunkt teleportieren.

Nächster Schritt
Im nächsten Schritt dieses Tutorials lernst du, wie du Spielern schnell sagen kannst, was sie in einem Spiel tun sollten und worauf du dich bei der Verbesserung des Spielerlebnisses konzentrieren solltest.