Znaczniki celów są używane w wielu grach, aby poprowadzić gracza do następnego celu lub miejsca na mapie. W tym samouczku dowiesz się, jak utworzyć znacznik celu wielokrotnego użytku za pomocą urządzenia znacznika na mapie i Verse.
Używane funkcje języka Verse
Metoda rozszerzająca: Specjalny typ funkcji działającej na zasadzie elementu członkowskiego istniejącej klasy lub typu bez konieczności tworzenia nowego typu lub podklasy. Z tym poradnikiem utworzysz metodę rozszerzającą dla struktury.
Nazwany argument: Argument, który jest przekazywany do wywołania funkcji z podaną nazwą parametru.
Używane interfejsy API Verse
creative_prop API:
creative_propAPI dostarcza metod umożliwiających ruch rekwizytów.Właściwości edytowalne: Kilka właściwości służy zarówno do odwoływania się do urządzeń, jak i aktualizowania wartości zmiennych w celu szybkiego testowania.
Instrukcje
Wykonaj poniższe kroki, aby dowiedzieć się, jak skonfigurować pojedyncze urządzenie znacznika celu, które może poruszać się do wielu celów lub miejsc na mapie. Kompletne skrypty znajdują się na końcu niniejszego poradnika.
Ustawianie poziomu
W tym przykładzie wykorzystano następujące rekwizyty i urządzenia:
1 x rekwizyt budowli: Rekwizyt, który będzie używany do poruszania urządzeniem znacznika na mapie.
1x urządzenie wskaźnika na mapie: Urządzenie wyświetlające niestandardowe znaczniki na minimapie i mapie ogólnej.
1x urządzenie panelu startowego gracza: Dodaj je w pobliżu rekwizytu, aby gracz odradzał się przy nim.
### Korzystanie z API rekwizytu
Pierwszym krokiem do wprowadzenia urządzenia w ruch za pomocą Verse jest przeniesienie rekwizytu za pomocą API rekwizytu. Wykonaj poniższe kroki, aby poruszać rekwizytem w obrębie poziomu.
Utwórz nowe urządzenie Verse o nazwie objective_coordinator_device.
Pod domyślnymi wyrażeniami
usingna górze pliku Verse, dodaj wyrażenieusingdla modułu SpatialMath. Ten moduł zawiera kod, który będzie używany do przenoszenia rekwizytów.Verseusing { /UnrealEngine.com/Temporary/SpatialMath }Dodaj dwie edytowalne właściwości:
Stała
creative_propo nazwieRootPropdo przechowywania odwołania do ruchomego rekwizytu.Stała
transformo nazwieDestinationdo przechowywania lokalizacji, do której rekwizyt będzie przenoszony.Verseobjective_coordinator_device<public> := class<concrete>(creative_device): @editable RootProp<public> : creative_prop = creative_prop{} @editable Destination<public> : transform = transform{}
Jeśli uruchomisz ten kod i przeciągniesz urządzenie objective_coordinator_device na swój poziom, zobaczysz dwie właściwości w panelu Szczegóły.
Metoda
TeleportTo[]jest tym, co faktycznie przenosi rekwizyt. Wywołaj ją w wyrażeniu if i użyj nawiasów kwadratowych zamiast okrągłych, ponieważTeleportTo[]jest wyrażeniem zawodnym. Wyrażenieifstwarza kontekst niepowodzenia.Verseif(RootProp.TeleportTo[Destination.Translation, Destination.Rotation]): Print("Prop move successful") else: Print("Prop move failed")Argumentami dla
TeleportTo[]są Translacja i Obrót. Oba pochodzą z właściwości Cel.Wróć do edytora i przeciągnij rekwizyt z Fortnite > Galerie > Rekwizyty w przeglądarce zawartości. Rekwizyt użyty w tym poradniku nazywa się Coastal Buoy 02B (Boja przybrzeżna 02B), ale każda pozycja z folderu Rekwizyty powinna działać.
Wybierz swoje urządzenie koordynatora celu w Outlinerze. W panelu Szczegóły ustaw w pozycji RootProp swój rekwizyt. W tym przykładzie w pozycji RootProp ustawiona jest boja przybrzeżna 02B.
W panelu Szczegóły rozwiń Cel. Cel ma przypisany typ
transform, dlatego składa się z komponentów Skala, Obrót i Translacja. Aby przenieść rekwizyt, wystarczy zmienić ustawienie Translacja, więc je rozwiń. Ustaw pole kończące się na X na 5000.0.Podczas testowania kodu dobrym rozwiązaniem jest wprowadzanie dużych zmian w wartościach, aby efekty były oczywiste. Niewielkie zmiany mogą utrudnić stwierdzenie, czy kod robi to, czego oczekujesz.
Verseusing { /Verse.org/Simulation } using { /Fortnite.com/Devices } using { /UnrealEngine.com/Temporary/SpatialMath } objective_coordinator_device<public> := class<concrete>(creative_device): @editable RootProp<public> : creative_prop = creative_prop{} # Where the marker will be moved toKliknij Verse, następnie Skompiluj kod Verse, po czym kliknij Uruchom sesję. Na koniec kliknij Uruchom grę. Rekwizyt powinien się poruszyć.
Klasa bazowa i struktury
Masz teraz rekwizyt poruszający się po twoim poziomie, ale prawdziwym celem jest poruszanie się urządzenia znacznika na mapie, aby gracze mogli go użyć jako punktu nawigacyjnego. Wykonaj poniższe kroki, aby dodać rekwizyt budowli i urządzenie znacznika na mapie do poziomu, a następnie dołączyć je do rekwizytu budowli.
Kliknij prawym przyciskiem myszy wewnątrz przeglądarki zawartości, aby otworzyć menu kontekstowe.
Wybierz opcję Klasa Blueprintu z menu kontekstowego.
W oknie Wybierz klasę bazową kliknij Rekwizyt budowli.
W Przeglądarce zawartości pojawi się nowa klasa Blueprint. Zmień jej nazwę na BuildingProp.
Przeciągnij rekwizyt budowli na swój poziom. Ten rekwizyt nie ma siatki, więc zobaczysz tylko jego gizmo przekształcenia.
W panelu Outliner przeciągnij urządzenie znacznika na mapie na rekwizyt budowli. W ten sposób rekwizyt budowli staje się klasą bazową urządzenia znacznika na mapie. Teraz, gdy rekwizyt budowli się porusza, urządzenie znacznika na mapie porusza się wraz z nim.
Wiesz już, jak utworzyć urządzenie za pomocą Verse, ale możesz także tworzyć pliki Verse, które nie mają własnych urządzeń.
Utwórz nowy plik Verse i nazwij go objective_marker. Ten plik nie utworzy urządzenia. Zamiast tego będzie zawierał definicję
struct, która będzie dostępna dla urządzenia Verse utworzonego wcześniej.Zacznij od zadeklarowania elementu
structo nazwie objective_marker. Będzie on miał dwa elementy członkowskie:RootPropiMapIndicator. Oba powinny mieć specyfikator@editable.Verseobjective_marker<public> := struct<concrete>: @editable RootProp<public> : creative_prop = creative_prop{} @editable MapIndicator<public> : map_indicator_device = map_indicator_device{}
Metody rozszerzające i argumenty nazwane
Zadeklaruj pojedynczą metodę, MoveMarker, która przesunie element RootProp i dołączone do niego urządzenie znacznika na mapie. Metoda ta wprowadza dwie cechy języka: metody rozszerzające i argumenty nazwane.
(Marker : objective_marker).MoveMarker<public>(Transform : transform, ?OverTime : float)<suspends> : void =Metody rozszerzająca: Dodajesz metodę
MoveMarker()do strukturyobjective_marker. Metoda rozszerzająca jest deklarowana przy użyciu nawiasów otaczających identyfikator i typ oddzielone dwukropkiem. W tym przypadku:(Marker : objective_marker).Argumenty nazwane: Drugi argument
?OverTimeużywa?do wskazania, że musi być nazwany w wywołaniu funkcjiMoveMarker. Pomaga to każdemu twórcy czytającemu lub piszącemu wywołanieMoveMarkerzrozumieć, co robi argumentfloat.
Funkcja MoveMarker() wywoła jedną z dwóch metod z API rekwizytu: TeleportTo[], która została użyta wcześniej, lub MoveTo(). Utwórz blok if..else, aby sprawdzić, czy parametr OverTime jest większy niż 0.0. Jeśli tak, wywołaj MoveTo(). Spowoduje to, że zamiast natychmiastowej teleportacji, twój cel przeniesiony zostanie do następnej lokalizacji w określonym przez ciebie czasie.
(Marker : objective_marker).MoveMarker<public>(Transform : transform, ?OverTime : float)<suspends> : void =
if (OverTime > 0.0):
Marker.RootProp.MoveTo(Transform.Translation, Transform.Rotation, OverTime)
else:
if:
Marker.RootProp.TeleportTo[Transform.Translation, Transform.Rotation]Jeśli teraz skompilujesz kod, powinno się to udać, ale nie zobaczysz nowego urządzenia w folderze CreativeDevices w przeglądarce zawartości. Dzieje się tak, ponieważ objective_marker jest obiektem struct, a nie klasą dziedziczącą po creative_device.
Aktualizacja urządzenia koordynatora celu
Teraz, gdy masz nowy typ do odwołania, musisz zaktualizować urządzenie objective_coordinator_device, aby się do niego odwoływać.
Usuń właściwość
RootPropi zastąp ją właściwością o nazwiePickupMarkertypuobjective_marker. Jest to typ utworzony przez ciebie.Funkcja
MoveMarker()wymaga argumentu typufloat, więc utwórz go jako edytowalną właściwość o nazwieMoveTime.Usuwa wywołanie
TeleportTo[]. Zamiast tego wywołaj metodęMoveMarker()utworzoną dlaobjective_marker. Wymaga ona podania argumentu?OverTime.Verseobjective_coordinator_device<public> := class<concrete>(creative_device): @editable PickupMarker<public> : objective_marker = objective_marker{} # Where the marker will be moved to @editable Destination<public> : transform = transform{} # How much time the marker should take to reach its new location
Skompiluj ten kod i sprawdź szczegóły urządzenia koordynatora celu. Widoczne powinny być właściwości PickupMarker i MoveTime, a właściwość PickupMarker powinna zawierać elementy RootProp i MapIndicator.
Ustaw pole RootProp na BuildingProp, a pole MapIndicator na Urządzenie znacznika na mapie
Skompiluj swój kod i kliknij Uruchom sesję. Na minimapie powinien pojawić się znacznik, który poruszy się wkrótce po rozpoczęciu gry. Wypróbuj go z
MoveTimeustawionym na różne wartości, w tym0.0. Zastanów się, który ruch byłby najlepszy dla różnych scenariuszy.
GetPlayers() i ActivateObjectivePulse()
Istnieje sposób na zapewnienie graczom dodatkowej pomocy w dotarciu do następnego celu. Nazywa się on impulsem celu. Gdy funkcja ta jest aktywna, pokazuje kropkowaną linię, która przesuwa się od gracza w kierunku urządzenia znacznika na mapie. Postępuj zgodnie z poniższymi instrukcjami, aby dodać impuls celu do urządzenia koordynatora celu.
Metoda potrzebna do aktywacji impulsu celu nazywa się ActivateObjectivePulse() i wymaga jednego argumentu typu agent. Zacznij od stworzenia metody pobierającej instancję agent reprezentującą postać gracza.
Zadeklaruj funkcję o nazwie
FindPlayer()ustawioną na<private>, z wartością zwracanąvoid.Pobierz tablicę z wszystkimi graczami na twoim poziomie za pomocą
Self.GetPlayspace().GetPlayers(). Przechowaj tablicę w zmiennej o nazwieAllPlayers.VerseFindPlayer<private>() : void = AllPlayers := Self.GetPlayspace().GetPlayers()Aby uzyskać odwołanie tylko do jednego gracza na poziomie, przypisz pierwszy element tablicy do jego własnej zmiennej. Uzyskanie dostępu do tablicy jest wyrażeniem zawodnym, więc umieść je w wyrażeniu
if.Verseif (FirstPlayer := AllPlayers[0]):Przypisanie
playerdo zmiennej może się nie powieść, dlatego należy użyć zmiennej typu option podczas odwoływania się do gracza w kodzie. Zadeklaruj opcjonalną zmienną gracza?player. Powinna być ona zgodna z innymi zmiennymi elementami członkowskimi.Verseobjective_coordinator_device<public> := class<concrete>(creative_device): var PlayerOpt<private> : ?player = false @editable PickupMarker<public> : objective_marker = objective_marker{} # Where the marker will be moved to @editable Destination<public> : transform = transform{}Ustaw nową zmienną i utwórz blok
elsez wyrażeniemPrint(), które poinformuje cię, jeśli gracz nie został znaleziony. Twoja funkcjaFindPlayer()jest teraz ukończona.VerseFindPlayer<private>() : void = # Since this is a single player experience, the first player [0] # should be the only one available. AllPlayers := Self.GetPlayspace().GetPlayers() if (FirstPlayer := AllPlayers[0]): set PlayerOpt = option{FirstPlayer} Print("Player found")
Wracając do funkcji OnBegin(), musisz wprowadzić jeszcze dwie zmiany:
Wywołaj funkcję
FindPlayer().VerseOnBegin<override>()<suspends> : void = FindPlayer()Po wywołaniu
MoveMarker()użyj kolejnego wyrażeniaif, aby ustawić opcjonalną zmienną gracza na nową zmienną i przekaż ją jako argument doPickupMarker.MapIndicator.ActivateObjectivePulse()Verseif (FoundPlayer := PlayerOpt?): PickupMarker.MapIndicator.ActivateObjectivePulse(FoundPlayer)
Jeśli uruchomisz teraz swój kod, zobaczysz impuls celu skierowany od twojej postaci do lokalizacji znacznika celu na poziomie!
Kompletne skrypty
Objective_marker.verse
using { /Verse.org/Simulation }
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Fortnite.com/Devices/CreativeAnimation }
objective_marker<public> := struct<concrete>:
# The prop that will be moved
@editable
RootProp<public> : creative_prop = creative_prop{}
Objective_coordinator_device.verse
using { /Verse.org/Simulation }
using { /Fortnite.com/Devices }
using { /Fortnite.com/Playspaces }
using { /UnrealEngine.com/Temporary/SpatialMath }
objective_coordinator_device<public> := class<concrete>(creative_device):
var PlayerOpt<private> : ?player = false
@editable
Praca własna
Pamiętaj, że napisany tutaj kod ruchu działa dla każdego rekwizytu. Jeśli ruchomy rekwizyt stanie się elementem nadrzędnym urządzenia, to urządzenie będzie poruszać się wraz z nim. Spróbuj poruszać innymi rekwizytami i urządzeniami oraz sprawdź, czy uda ci się wymyślić inne gry, w których można by wykorzystać te efekty.
Kolejne kroki
Jeśli korzystasz z tego poradnika do stworzenia gry bazującej na odbiorze i dostarczeniu, następnym krokiem jest nauczenie się, jak utworzyć funkcję licznika czasu odliczania.