Możesz użyć urządzenia licznika czasu które uruchamia odliczanie czasu, ale dzięki stworzeniu własnego licznika czasu odliczania w Verse możesz dostosować jego zachowanie do swoich potrzeb.
Z tego samouczka dowiesz się, jak stworzyć własny licznik czasu za pomocą Verse i jak używać wywołania, gdy czas jest dodawany do odliczania. Zacznij od prostego przykładu, a z czasem znajdziesz sposób na jego ulepszenie, projekt po projekcie.
Używane funkcje języka Verse
if: Wyrażenie
if
testuje warunki i uzyskuje dostęp do wartości, które mogą zakończyć się niepowodzeniem.block: w tym przykładzie użyto wyrażenia
block (blok)
do zainicjowania UI po utworzeniu licznika czasu odliczania.loop: Wyrażenie
loop
aktualizuje UI i kończy się, gdy odliczanie dojdzie do zera.spawn: Wyrażenie
spawn
rozpoczyna wyrażenie asynchroniczne w dowolnym kontekście.message: typ message (komunikat) oznacza, że tekst da się zlokalizować, a ciąg użyty do zainicjowania zmiennej message jest domyślnym tekstem i językiem komunikatu.
class: Ten przykład tworzy klasę Verse, która wyświetla odliczanie i zarządza nim.
constructor (konstruktor): konstruktor to specjalna funkcja, która tworzy instancję klasy, z którą jest związana.
Specyfikatory dostępu: Za pomocą specyfikatorów dostępu możesz określić poziom dostępu do swojego kodu.
Używane interfejsy API Verse
Sleep: Za pomocą interfejsu API
Sleep()
możesz wybrać okres pomiędzy aktualizacjami UI.Zdarzenia: W Verse możesz tworzyć własne zdarzenia i dodawać do nich funkcje niestandardowe inicjowane w chwili ich wystąpienia.
Interfejs użytkownika Verse: Utwórz niestandardowy UI w grze, aby wyświetlać informacje o graczu i grze.
Instrukcje
Postępuj zgodnie z poniższą instrukcją, aby dowiedzieć się, jak utworzyć niestandardowy licznik czasu. Do celów odniesienia, na końcu tego przewodnika znajduje się kompletny skrypt.
Ustawianie poziomu
W tym przykładzie wykorzystano następujące rekwizyty i urządzenia:
1 x Urządzenie przycisku: Gdy gracz wchodzi w interakcję z urządzeniem, do odliczania dodaje się więcej czasu.
1 x Urządzenie końca gry: Po zakończeniu odliczania urządzenie to powoduje zakończenie gry.
Postępuj zgodnie z poniższą instrukcją, aby skonfigurować swój poziom:
Dodaj urządzenie Przycisk i urządzenie Koniec gry do poziomu.
Utwórz nowe urządzenie Verse i nadaj mu nazwę
countdown_timer_example
za pomocą Eksploratora Verse. Aby poznać kroki, patrz: Tworzenie własnego urządzenia przy użyciu Verse.Dodaj edytowalne odwołanie do urządzenia przycisku w urządzeniu
countdown_timer_example
i nazwij jeAddMoreTimeButton
. Aby poznać kroki, patrz: Dostosowywanie właściwości urządzenia.Versecountdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{}
Dodaj edytowalne odwołanie do urządzenia końca gry w urządzeniu
countdown_timer_example
i nazwij jeEndGame
.Versecountdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{} @editable EndGame : end_game_device = end_game_device{}
Zapisz plik Verse, a następnie w menu głównym UEFN wybierz Verse > Skompiluj kod Verse, aby zaktualizować urządzenie w poziomie i zobaczyć zmiany w panelu Szczegóły urządzenia.
Rozpoczynanie odliczania
W tym przykładzie utworzysz klasę Verse, która rysuje własny UI i zarządza własnym odliczaniem.
Postępuj zgodnie z poniższą instrukcją, aby utworzyć niestandardowy licznik czasu odliczania:
Utwórz pusty plik Verse i nazwij go countdown_timer.verse.
Na początku pliku dodaj następujące moduły Verse:
Verseusing { /UnrealEngine.com/Temporary/UI } using { /UnrealEngine.com/Temporary/SpatialMath } using { /Fortnite.com/UI } using { /Verse.org/Colors } using { /Verse.org/Simulation }
Utwórz klasę i nazwij ją
countdown_timer
, a następnie dodaj następujące zmienne:* Zmienna typu float o nazwie
RemainingTime
i zainicjowana do0.0
.Versevar RemainingTime : float = 0.0
* Zmienna widżetu elementu canvas o nazwie
Canvas
.Versevar Canvas : canvas = canvas{}
Widżet tekstowy o nazwie
RemainingTimeWidget
z domyślnym białym kolorem tekstu.VerseRemainingTimeWidget : text_block = text_block{DefaultTextColor := NamedColors.White}
Funkcja zwracająca wiadomość o nazwie
RemainingTimeText
, która przyjmuje parametr liczby całkowitej, aby wyświetlić wartość reprezentowaną przezRemainingTime
.VerseRemainingTimeText<localizes>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"
Opcjonalny UI gracza o nazwie
MaybePlayerUI
i zainicjowany do wartościfalse
.VerseMaybePlayerUI : ?player_ui = false
Twoja klasa powinna wyglądać tak:
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}"
Dodaj wyrażenie
block
, aby utworzyć UI, w którym zegar pojawia się w górnej środkowej części ekranu. Wyrażenie block w definicji klasy działa tylko wtedy, gdy tworzona jest instancja klasy, więc możemy utworzyć UI raz w tym wyrażeniublock
.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}
Dodaj funkcję
StartCountdown()
, aby wyświetlić UI.VerseStartCountdown() : void = Print("Starting countdown") if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas)
W urządzeniu countdown_timer_example.verse utwórz instancję
countdown_timer
z odwołaniem do UI gracza i początkowym czasem odliczania. WywołajStartCountdown()
wOnBegin()
, tak aby odliczanie pojawiło się zaraz po rozpoczęciu gry.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{}
Jeśli teraz prowadzisz test gry, UI nie wyświetla pozostałego czasu, kiedy rozpoczyna się odliczanie, więc w pliku countdown_timer.verse, utwórz funkcję i nazwij ją
UpdateUI()
; będzie ona aktualizować bieżącą wartość odliczania w UI. WywołajUpdateUI()
wStartCountdown()
.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 =
Teraz w UI pojawia się początkowe odliczanie, ale wartość nie jest aktualizowana co sekundę. W tym celu:
Dodaj zmienną typu float
TimerTickPeriod
, która będzie reprezentować częstotliwość aktualizacji UI w sekundach. W tym przykładzie użyto jednej sekundy.VerseTimerTickPeriod : float = 1.0 # The timer "precision": how often, in seconds, it ticks.
Utwórz funkcję o nazwie
RunCountdown()
, która ma specyfikator suspends, i wywołaj ją zStartCountdown()
. NiechRunCountdown()
odczeka przezTimerTickPeriod
przed aktualizacją UI, a następnie powtórz te operacje w pętli. Ustaw zakończenie pętli i skonfiguruj odliczanie tak, aby zniknęło z UI, gdy odliczanie osiągnie wartość0.0
.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:
Podczas testu gry odliczanie powinno rozpocząć się od 30 i aktualizować się co sekundę, aż do momentu, gdy licznik osiągnie wartość 0 i odliczanie zniknie z UI.
Dodawanie więcej czasu
W przypadku tego licznika czasu odliczania możesz dodać niestandardowy sposób dodawania czasu i wywoływania dodanego czasu. Na przykładzie pokazano, jak dodać więcej czasu do odliczania i wyświetlić ten czas, gdy gracz wejdzie w interakcję z urządzeniem przycisku.
Postępuj zgodnie z poniższą instrukcją, aby dodać więcej czasu do licznika czasu odliczania, gdy gracz wejdzie w interakcję z urządzeniem przycisku:
W countdown_timer.verse, nową funkcję o nazwie
AddRemainingTime()
, która aktualizuje zmiennąRemainingTime
o wartość przekazaną do funkcji w parametrze typu float o nazwieTime
, a następnie aktualizuje UI, aby pokazywał nowy pozostały czas.VerseAddRemainingTime(Time : float) : void = set RemainingTime += Time # Immediately update the UI for better player feedback when time is added. UpdateUI()
W urządzeniu countdown_timer_example.verse zasubskrybuj
InteractedWithEvent
urządzenia przycisku i wywołajAddRemainingTime()
, gdy gracz wchodzi w interakcję z urządzeniem przycisku.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{}
Do klasy
countdown_timer
dodaj widżet, który będzie pokazywał, ile czasu zostało dodane do odliczania, gdy gracz wejdzie w interakcję z przyciskiem.VerseAddedTimeWidget : text_block = text_block{DefaultTextColor := NamedColors.White} AddedTimeText<localizes>(AddedTime : int) : message = " +{AddedTime}!"
Do nowego widżetu AddedTimeWidget użyj tych samych wartości pozycjonowania, co w przypadku widżetu RemainingTime, ale zmień następujące wartości, aby wywoływany czas wyświetlał się w prawym górnym rogu licznika czasu odliczania:
Dla AddedTimeWidget ustaw Lewy margines w Przesunięcia na
50.0
.Dla RemainingTimeWidget ustaw Górny margines w Przesunięcia na
25.0
.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}
Utwórz nową funkcję o nazwie
AddedTimeCallout()
, która aktualizuje wartość w widżecie AddedTimeWidget i wyświetla wywołanie przez dwie sekundy, po czym ponownie ukrywa widżet. WywołajAddedTimeCallout()
wAddRemainingTime()
.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)
Podczas testu gry odliczanie powinno rozpocząć się od 30 i aktualizować się co sekundę, aż do momentu, gdy licznik czasu osiągnie wartość 0 i odliczanie zniknie z UI. Gdy gracz wejdzie w interakcję z przyciskiem, do odliczania zostanie dodane dwadzieścia sekund, a na dwie sekundy pojawi się wywołanie pokazujące dodatkowy czas.
Sygnalizowanie zakończenia odliczania
Wcześniej w tym samouczku używaliśmy urządzenia przycisku InteractedWithEvent
, aby sprawdzić, kiedy gracz nacisnął przycisk, i dodać więcej czasu do licznika czasu odliczania. Ale można też tworzyć zdarzenia niestandardowe, których inni mogą używać, aby wiedzieć, kiedy coś się dzieje w kodzie.
Poniższy przykład przedstawia sposób wykorzystania następującego zachowania zdarzeń niestandardowych:
Signal()
: Funkcja ta informuje wszystkich oczekujących na zdarzenie o tym, że zdarzenie miało miejsce.Await()
: Ta asynchroniczna funkcja blokuje wykonanie otaczającego kontekstu do momentu zasygnalizowania zdarzenia.
W tym przykładzie do licznika czasu odliczania dodasz zdarzenie, aby zasygnalizować zakończenie odliczania, dzięki któremu będzie można aktywować urządzenie końca gry.
Postępuj zgodnie z poniższą instrukcją, aby dodać zdarzenie kończące odliczanie.
Dodaj pole zdarzenia o nazwie
CountdownEndedEvent
do klasycountdown_timer
:VerseCountdownEndedEvent : event() = event(){}
Typ
event()
jest typem parametrycznym, co oznacza, że zwraca klasę lub interfejs, a nie wartość lub instancję obiektu. Właśnie dlatego typem jestevent()
, więc musisz zainicjować stałąCountdownEndedEvent
za pomocąevent(){}
, aby naśladować sposób, w jaki tworzy się klasę.Zaktualizuj
RunCountdown()
w celu zasygnalizowania zdarzeniaCountdownEndedEvent
, aby poinformować inny kod o zakończeniu odliczania przed wyjściem z pętli.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):
W countdown_timer_example.verse zaczekaj na zdarzenie
CountdownEndedEvent
powiązane zCountdownTimer
, a następnie aktywuj urządzenie końca gry, ponieważ wiemy, że odliczanie się skończyło wraz z wystąpieniem tego zdarzenia.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()
Podczas testu gry odliczanie powinno rozpocząć się od 30 i aktualizować się co sekundę, aż do momentu, gdy licznik czasu osiągnie wartość 0. Gdy odliczanie się skończy, zniknie ono z UI i gra się zakończy. Gdy gracz wejdzie w interakcję z przyciskiem, do odliczania zostanie dodane dwadzieścia sekund, a na dwie sekundy pojawi się wywołanie pokazujące dodatkowy czas.
Przygotowywanie klasy do użycia przez inny kod
Właśnie udało ci się utworzyć własną klasę niestandardowego licznika czasu odliczania i użyć urządzenia stworzonego w Verse do jego zainicjowania i sterowania nim.
Kiedy tworzysz klasy niestandardowe (i tak naprawdę każdy kod), ważne jest, aby określić, kto może mieć dostęp do tego, co tworzysz. Na przykład tylko licznik czasu odliczania powinien mieć możliwość tworzenia i zmieniania swojego UI. Za pomocą specyfikatorów dostępu możesz określić poziom dostępu do swojego kodu.
Dodaj specyfikator public
do wszystkich identyfikatorów, które chcesz udostępnić innym, ponieważ public (dostęp publiczny) oznacza, że identyfikator jest powszechnie dostępny. W tym przykładzie wszystkie poniższe elementy są używane w urządzeniu countdown_timer_example
, a więc dostęp do nich powinien być publiczny:
CountdownEndedEvent<public> : event() = event(){}
StartCountdown<public>() : void =
AddRemainingTime<public>(Time : float) : void =
Dodaj specyfikator private
do wszystkich identyfikatorów, do których nie chcesz, aby inni mieli dostęp, ponieważ private (dostęp prywatny) oznacza, że identyfikator może być dostępny tylko w bieżącym, bezpośrednio otaczającym zakresie (którym w tym przypadku jest klasa countdown_timer
).
W tym przykładzie dostęp do następujących elementów powinien być prywatny:
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 =
Warto pogrupować swój kod według poziomu dostępu. Zalecamy uporządkowanie kodu od najwyższego do najniższego poziomu dostępu:
publiczne
Wewnętrzny
chronione
prywatne
Możesz użyć konstruktora do ustawienia wartości początkowych dla nowej instancji klasy bez uwidaczniania jej zmiennych. Konstruktor to specjalna funkcja, która tworzy instancję klasy, z którą jest związana.
Utwórz dla klasy countdown_timer
konstruktora, który aktualizuje zmienne RemainingTime
i MaybePlayerUI
.
MakeCountdownTimer<constructor><public>(MaxTime : float, InPlayer : agent) := countdown_timer:
RemainingTime := MaxTime
MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
Dostęp do zmiennych RemainingTime
i MaybePlayerUI
ustawionych w konstruktorze nie powinien być publiczny, ale nie może być prywatny, jeśli są one ustawione w konstruktorze. W przypadku tych zmiennych możesz użyć specyfikatora internal (dostęp wewnętrzny)
, co oznacza, że dostęp do identyfikatora jest możliwy tylko w bieżącym, bezpośrednio otaczającym module.
MaybePlayerUI<internal> : ?player_ui = false
var RemainingTime<internal> : float = 0.0
Complete Code
Poniżej znajduje się kompletny kod do utworzenia niestandardowego licznika czasu odliczania.
W tym przykładzie utworzono dwa pliki Verse.
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
Praca własna
Dzięki tej instrukcji wiesz już, jak stworzyć niestandardowy licznik czasu odliczania.
Wykorzystując zdobytą wiedzę, spróbuj wykonać następujące czynności:
Zmień częstotliwość tykania licznika czasu i dodaj zdarzenie dla każdego tyknięcia.
Dodaj do licznika czasu funkcję wstrzymywania, wznawiania i ponownego uruchamiania.