Du könntest das Timer-Gerät verwenden, das einen Countdown-Timer ausführt, aber die Erstellung eines eigenen Countdown-Timers in Verse ist eine Möglichkeit, sein Verhalten genau an deine Bedürfnisse anzupassen.
In diesem Tutorial erfährst du, wie du deinen eigenen Timer mit Verse erstellst und wie du einen Appell verwendest, wenn die Zeit zum Countdown hinzugefügt wird. Fang einfach an, und du wirst Wege finden, dein Können zu verbessern, Projekt für Projekt.
Verwendete Sprachfunktionen in Verse
if: Der Ausdruck
if
testet Bedingungen und greift auf Werte zu, die fail sein könnten.block: In diesem Beispiel wird der Ausdruck
block
zum initialize der Benutzeroberfläche verwendet, wenn der Countdown-Timer erstellt wird.loop: Der Ausdruck
loop
aktualisiert die Benutzeroberfläche und endet, wenn der Countdown Null erreicht.spawn: Ein
spawn
Ausdruck startet eine asynchronous expression in einem beliebigen context.message: Der Nachrichtentyp bedeutet, dass der Text lokalisiert werden kann, und die Zeichenfolge, die du zum Initialisieren einer Nachrichtenvariablen verwendest, ist der Standardtext und die Standardsprache für die Nachricht.
classDieses Beispiel erstellt eine Verse-Klasse, die den Countdown verwaltet und anzeigt.
constructor: Ein Constructor ist eine spezielle Funktion, die eine Instanz der Klasse erzeugt, mit der sie verbunden ist.
Access specifiers: Mithilfe von Zugriffsbezeichnern kannst du die Zugriffsebene deines Codes festlegen.
Verwendete APIs in Verse
Sleep: Mit der API
Sleep()
kannst du den Zeitraum zwischen UI-Aktualisierungen auswählen.Events: Du kannst deine eigenen Ereignisse in Verse erstellen und benutzerdefinierte Funktionen hinzufügen, wenn sie auftreten.
Verse UI: Erstelle eine benutzerdefinierte In-Game-Benutzeroberfläche, um Informationen über den Spieler und das Spiel anzuzeigen.
Anweisungen
Befolge diese Schritte, um zu erfahren, wie du deinen eigenen benutzerdefinierten Timer erstellst. Das complete script ist am Ende dieses Leitfadens als Referenz enthalten.
Level einrichten
Dieses Beispiel verwendet die folgenden Props und Geräte.
1 x Schaltflächengerät: Wenn der Spieler mit dem Gerät interagiert, wird dem Countdown mehr Zeit hinzugefügt.
1 x Endspielgerät: Wenn der Countdown abgelaufen ist, bewirkt dieses Gerät, dass das Spiel beendet wird.
Befolge diese Schritte, um dein Level einzurichten:
Füge ein Gerät Schaltfläche und Spielbeender zu deinem Level hinzu.
Erstelle ein neues Verse-Gerät mit dem Namen
countdown_timer_example
mit Verse Explorer. Weitere Schritte findest Du unter Erstellen eines eigenen Geräts mit Verse.Füge eine Referenz editable zum Schaltflächengerät in
countdown_timer_example
mit dem NamenAddMoreTimeButton
hinzu. Weitere Schritte findest Du unter Customize Device Properties.Versecountdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{}
Füge einen bearbeitbaren Verweis auf das Spielbeender-Gerät in
countdown_timer_example
mit dem NamenEndGame
hinzu.Versecountdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{} @editable EndGame : end_game_device = end_game_device{}
Speichere deine Verse-Datei und wähle im UEFN-Hauptmenü Verse > Verse-Code erstellen, um dein Gerät im Level zu aktualisieren und deine Änderungen im Panel Details des Geräts zu sehen.
Starten des Countdown
In diesem Beispiel erstellst du eine Verse-Klasse, die ihre eigene Benutzeroberfläche zeichnet und ihren eigenen Countdown verwaltet.
Befolge diese Schritte, um deinen benutzerdefinierten Countdown-Timer zu erstellen:
Erstelle eine leere Verse-Datei mit dem Namen countdown_timer.verse.
Füge die folgenden Verse-Module am Anfang der Datei hinzu:
Verseusing { /UnrealEngine.com/Temporary/UI } using { /UnrealEngine.com/Temporary/SpatialMath } using { /Fortnite.com/UI } using { /Verse.org/Colors } using { /Verse.org/Simulation }
Erstelle eine Klasse mit dem Namen
countdown_timer
, und füge die folgenden Variablen hinzu:Eine float-Variable mit dem Namen
RemainingTime
und initialisiert auf0.0
.Versevar RemainingTime : float = 0.0
Eine Canvas-Widget-Variable mit dem Namen
Canvas
.Versevar Canvas : canvas = canvas{}
Ein Text-Widget mit dem Namen
RemainingTimeWidget
mit einer weißen Standardtextfarbe.VerseRemainingTimeWidget : text_block = text_block{DefaultTextColor := NamedColors.White}
Eine Funktion, die eine Nachricht mit dem Namen
RemainingTimeText
zurückgibt, die eine Ganzzahl parameter annimmt, um den durchRemainingTime
dargestellten Wert anzuzeigen.VerseRemainingTimeText<localizes>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"
Eine optionale Player-UI mit dem Namen
MaybePlayerUI
die auffalse
initialisiert wird.VerseMaybePlayerUI : ?player_ui = false
Deine Klasse sollte folgendermaßen aussehen:
Versecountdown_timer := class: MaybePlayerUI : ?player_ui = false var RemainingTime : float = 0.0 var Canvas : canvas = canvas{} RemainingTimeWidget : text_block = text_block{DefaultTextColor := NamedColors.White} RemainingTimeText<localizes>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"
Füge einen Ausdruck
block
hinzu, um die Benutzeroberfläche zu erstellen, in der die Zeit in der oberen Mitte des Bildschirms angezeigt wird. Ein Ausdruck block in einer Klassendefinition wird nur ausgeführt, wenn die Klasse instanziiert wird, sodass wir die Benutzeroberfläche einmal in diesem Ausdruckblock
erstellen können.Versecountdown_timer := class: block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors: Minimum := vector2{X := 0.5, Y := 0.05} Maximum := vector2{X := 0.5, Y := 0.05} Alignment := vector2{X := 0.5, Y := 0.0} Offsets := margin{Top := 0.0, Left := 0.0, Bottom := 0.0, Right := 0.0}
Füge die Funktion
StartCountdown()
hinzu, um die Benutzeroberfläche anzuzeigen.VerseStartCountdown() : void = Print("Starting countdown") if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas)
Erstelle in countdown_timer_example.verse eine Instanz
countdown_timer
mit einem Verweis auf die Benutzeroberfläche des Spielers und die anfängliche Countdown-Zeit. Sobald das Spiel beginnt, rufeStartCountdown()
inOnBegin()
auf, damit der Countdown erscheint.Verseusing { /Verse.org/Simulation } using { /Fortnite.com/Devices } countdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{} @editable EndGame : end_game_device = end_game_device{}
Wenn du jetzt einen Spieltest durchführst, zeigt die Benutzeroberfläche nicht die verbleibende Zeit an, wenn der Countdown beginnt. Erstelle daher in countdown_timer.verse, Erstelle eine Funktion mit dem Namen
UpdateUI()
, die den aktuellen Countdown-Wert in der Benutzeroberfläche aktualisiert. RufeUpdateUI()
inStartCountdown()
auf.VerseStartCountdown() : void = Print("Starting countdown") if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas) # Update the UI when we start the timer to see the initial RemainingTime on screen UpdateUI() UpdateUI() : void =
Jetzt erscheint der anfängliche Countdown in der Benutzeroberfläche, aber der Wert wird nicht jede Sekunde aktualisiert. Das tut ihr auf folgende Weise:
Füge die float-Variable
TimerTickPeriod
hinzu, um anzugeben, wie oft die Benutzeroberfläche in Sekunden aktualisiert werden soll. In diesem Beispiel wird eine Sekunde verwendet.VerseTimerTickPeriod : float = 1.0 # The timer "precision": how often, in seconds, it ticks.
Erstelle eine Funktion mit dem Namen
RunCountdown(),
die den suspends specifier enthält, und rufe sie vonStartCountdown()
auf. LassRunCountdown()
dieTimerTickPeriod
abwarten, bevor du die Benutzeroberfläche aktualisierst, und wiederhole dies im loop. Stelle die Schleife auf Ende ein und lasse den Countdown von der Benutzeroberfläche verschwinden, wenn der Countdown0,0
erreicht.VerseStartCountdown() : void = Print("Starting countdown") if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas) # Update the UI when we start the timer to see the initial RemainingTime on screen UpdateUI() spawn:
Beim Spieltest sollte der Countdown bei 30 beginnen und jede Sekunde aktualisiert werden, bis der Timer 0 erreicht und der Countdown dann von der Benutzeroberfläche verschwindet.
Mehr Zeit hinzufügen
Mit diesem Countdown-Timer möchtest du eine benutzerdefinierte Möglichkeit hinzufügen, um mehr Zeit hinzuzufügen und die hinzugefügte Zeit auszurufen. Dieses Beispiel zeigt, wie man dem Countdown mehr Zeit hinzufügt und die hinzugefügte Zeit anzeigt, wenn der Spieler mit dem Gerät Schaltfläche interagiert.
Befolge diese Schritte, um zum Countdown-Timer mehr Zeit hinzuzufügen, wenn der Spieler mit dem Schaltflächengerät interagiert:
In countdown_timer.verse Erstelle eine neue Funktion mit dem Namen
AddRemainingTime()
, die die VariableRemainingTime
mit dem Wert aktualisiert, der der Funktion im float-Parameter mit dem NamenTime
übergeben wird, und dann die Benutzeroberfläche aktualisiert, um die neue verbleibende Zeit anzuzeigen.VerseAddRemainingTime(Time : float) : void = set RemainingTime += Time # Immediately update the UI for better player feedback when time is added. UpdateUI()
Abonniere in countdown_timer_example.verse das
InteractedWithEvent
des Schaltflächengeräts und rufeAddRemainingTime()
auf, wenn der Spieler mit dem Schaltflächengerät interagiert.Verseusing { /Verse.org/Simulation } using { /Fortnite.com/Devices } countdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{} @editable EndGame : end_game_device = end_game_device{}
Füge der Klasse
countdown_timer
ein Widget hinzu, das anzeigt, wie viel Zeit zum Countdown hinzugefügt wird, wenn der Spieler mit der Schaltfläche interagiert.VerseAddedTimeWidget : text_block = text_block{DefaultTextColor := NamedColors.White} AddedTimeText<localizes>(AddedTime : int) : message = " +{AddedTime}!"
Verwende dieselben Positionierungswerte wie das RemainingTime-Widget für das neue AddedTimeWidget, aber ändere die folgenden Werte, sodass die Appell-Zeit oben rechts neben dem Countdown-Timer angezeigt wird:
Lege für das AddedTimeWidget den linken Rand in Versatz auf
50.0
fest.Lege für das RemainingTimeWidget den oberen Rand in Versätzen auf
25.0
fest.Versecountdown_timer := class: <# This block runs for each instance of the countdown_timer class. We can setup the canvas once here. #> block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors: Minimum := vector2{X := 0.5, Y := 0.05} Maximum := vector2{X := 0.5, Y := 0.05}
Erstelle eine neue Funktion mit dem Namen
AddedTimeCallout()
, die den Wert im AddedTimeWidget aktualisiert und den Aufruf zwei Sekunden lang anzeigt, bevor sie das Widget wieder ausblendet. RufeAddedTimeCallout()
inAddRemainingTime()
auf.VerseAddRemainingTime(Time : float) : void = set RemainingTime += Time # Immediately update the UI for better player feedback when time is added. UpdateUI() # Fire a simple callout to show the time being added. spawn: AddedTimeCallout(Time)
Beim Spieltest sollte der Countdown bei 30 beginnen und jede Sekunde aktualisiert werden, bis der Timer 0 erreicht und der Countdown dann von der Benutzeroberfläche verschwindet. Wenn der Spieler mit der Schaltfläche interagiert, werden dem Countdown zwanzig Sekunden hinzugefügt, und es wird zwei Sekunden lang eine Legende angezeigt, die die zusätzliche hinzugefügte Zeit anzeigt.
Signalisierung des Ablaufs des Countdown-Timers
Zuvor hast du in diesem Tutorial ein Schaltflächengerät InteractedWithEvent
verwendet, um zu wissen, wann der Spieler die Schaltfläche gedrückt hat, und dem Countdown-Timer mehr Zeit hinzugefügt hat. Du kannst aber auch deine eigenen benutzerdefinierten Ereignisse erstellen, die andere verwenden können, um zu erfahren, wenn etwas in deinem Code passiert.
Dieses Beispiel zeigt, wie das folgende Verhalten von benutzerdefinierten Ereignissen verwendet wird:
Signal()
: Diese Funktion lässt jeden, der auf das Ereignis wartet, wissen, dass das Ereignis stattgefunden hat.Await()
: Diese asynchrone Funktion blockiert die Ausführung ihres einschließenden Kontexts, bis das Ereignis signalisiert wird.
In diesem Beispiel fügst du zum Countdown-Timer ein Ereignis hinzu, um zu signalisieren, wann der Countdown endet, damit du das Spielbeender-Gerät aktivieren kannst.
Befolge diese Schritte, um ein Ereignis für das Ende des Countdowns hinzuzufügen.
Füge der Klasse ein Ereignisfeld mit dem Namen
CountdownEndedEvent
countdown_timer
hinzu:VerseCountdownEndedEvent : event() = event(){}
Der
Event()
ist ein parametric type, was bedeutet, dass es eher eine Klasse oder ein Interface als einen Wert oder eine Objektinstanz gibt. Aus diesem Grund ist der Typevent()
, und daher musst du deine KonstanteCountdownEndedEvent
mitevent(){}
initialisieren, um nachzuahmen, wie du eine Klasse instanziierst.Aktualisiere
RunCountdown()
um denCountdownEndedEvent
zu signalisieren, um anderem Code mitzuteilen, dass der Countdown beendet ist, bevor er aus der Schleife ausbricht.VerseRunCountdown()<suspends> : void = # We loop with the TimerTickPeriod. # The UI is also updated each time. loop: Sleep(TimerTickPeriod) set RemainingTime -= TimerTickPeriod UpdateUI() # Timer End if (RemainingTime <= 0.0):
In countdown_timer_example.verse warte auf den
CountdownEndedEvent
der mit demCountdownTimer
verbunden ist, und aktiviere dann das Spielbeender-Gerät, da wir wissen, dass der Countdown beendet ist, wenn das Ereignis eintritt.VerseOnBegin<override()<suspends> : void = AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith) if: FirstPlayer := Self.GetPlayspace().GetPlayers()[0] PlayerUI := GetPlayerUI[player[FirstPlayer]] then: set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime} CountdownTimer.StartCountdown() CountdownTimer.CountdownEndedEvent.Await()
Beim Spieltest sollte der Countdown bei 30 beginnen und jede Sekunde aktualisiert werden, bis der Timer 0 erreicht. Sobald der Countdown endet, verschwindet der Countdown von der Benutzeroberfläche und das Spiel endet. Wenn der Spieler mit der Schaltfläche interagiert, werden dem Countdown zwanzig Sekunden hinzugefügt, und es wird zwei Sekunden lang ein Appell angezeigt, der die hinzugefügte Zeit anzeigt.
Bereitung deine Klasse für die Verwendung durch anderen Code vor
Du hast nun deine eigene benutzerdefinierte Countdown-Timer-Klasse erstellt und ein von Verse erstelltes Gerät verwendet, um den Timer zu instanziieren und zu steuern.
Wenn du deine eigenen benutzerdefinierten Klassen (und wirklich jeden Code) erstellst, ist es wichtig anzugeben, wer auf Ihre Erstellung zugreifen kann. Beispielsweise sollte nur der Countdown-Timer in der Lage sein, seine Benutzeroberfläche zu erstellen und zu ändern. In Verse kannst du access specifiers verwenden, um die Zugriffsebene deiner Codes festzulegen.
Füge die Kennung public
allen Kennungen hinzu, auf die andere zugreifen sollen, da public bedeutet, dass ddie Kennung allgemein zugänglich ist. In diesem Beispiel werden alle folgenden Elemente countdown_timer_example
im Gerät verwendet und sollten daher öffentlichen Zugang haben:
CountdownEndedEvent<public> : event() = event(){}
StartCountdown()<public>: void =
AddRemainingTime(Time<public>: float) : void =
Füge den Bezeichner private
zu allen Kennungen hinzu, wo die du nicht möchtest, dass andere darauf zugreifen, denn private bedeutet, dass auf die Kennung nur im aktuellen, unmittelbar umschließenden Bereich zugegriffen werden kann (der in diesem Fall die countdown_timer
-Klasse ist).
In diesem Beispiel sollte Folgendes privaten Zugriff haben:
RemainingTimeWidget<private> : text_block = text_block{DefaultTextColor := NamedColors.White}
AddedTimeWidget<private> : text_block = text_block{DefaultTextColor := NamedColors.White}
AddedTimeText<localizes><private>(AddedTime : int) : message = " +{AddedTime}!"
RemainingTimeText<localizes><private>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"
var Canvas<private> : canvas = canvas{}
TimerTickPeriod<private> : float = 1.0
RunCountdown<private>()<suspends> : void =
AddedTimeCallout<private>(Time : float)<suspends> : void =
UpdateUI<private>() : void =
Es ist eine gute Idee, deinen Code nach Zugriff zu gruppieren. Wir empfehlen, deinen Code von der größten bis zur geringsten Zugriffsmenge zu bestellen:
öffentlich
Intern
geschützt
privat
Du kannst einen constructor verwenden, um Ausgangswerte für eine neue Klasseninstanz festzulegen, ohne die Variablen einer Klasse exposing zu machen. Ein Konstruktor ist eine spezielle Funktion, die eine Instanz der Klasse erzeugt, mit der sie verbunden ist.
Erstelle einen Constructor für die Klasse countdown_timer
, der die Variablen RemainingTime
und MaybePlayerUI
aktualisiert.
MakeCountdownTimer<constructor><public>(MaxTime : float, InPlayer : agent) := countdown_timer:
RemainingTime := MaxTime
MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
Die Variablen RemainingTime
und MaybePlayerUI
, die im Constructor festgelegt sind, sollten keinen öffentlichen Zugriff haben, aber sie können keinen privaten Zugriff haben, wenn sie in einem Constructor festgelegt sind. Du kannst die Kennung internal
für diese Variablen verwenden, was bedeutet, dass auf die Kennung nur im aktuellen, unmittelbar einschließenden Modul zugegriffen werden kann.
MaybePlayerUI<internal> : ?player_ui = false
var RemainingTime<internal> : float = 0.0
Vollständiger Code
Der folgende Code ist der vollständige Code zum Erstellen eines benutzerdefinierten Countdown-Timers.
In diesem Beispiel werden zwei Verse-Dateien erstellt.
countdown_timer.verse
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
using { /Fortnite.com/UI }
MakeCountdownTimer<constructor><public>(MaxTime : float, InPlayer : agent) := countdown_timer:
RemainingTime := MaxTime
MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
countdown_timer_example.verse
using { /Verse.org/Simulation }
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/UI }
countdown_timer_example := class(creative_device):
@editable
AddMoreTimeButton : button_device = button_device{}
@editable
Du bist am Zug
Durch den Abschluss dieses Leitfadens hast du gelernt, wie du einen benutzerdefinierten Countdown-Timer erstellst.
Versuche mit dem, was du gelernt hast, Folgendes:
Ändere die Tickrate des Timers und füge ein Ereignis für jeden Tick hinzu.
Füge dem Timer Funktionen zum Pausieren, Fortsetzen und Neustarten hinzu.