Niewidoczność infiltratora stwarza interesujący problem, gdy trzeba przechwycić cel obrońców. W jaki sposób obrońcy mają odszukać niewidocznego gracza, który może właśnie pędzić z powrotem do swojej bazy z ich celem? Aby rozwiązać ten problem, możesz wykorzystać pomoc wizualną (w tym przypadku rekwizyt), która wskaże obrońcom, gdzie znajduje się infiltrator.
Poniższa procedura ilustruje sposób tworzenia obiektu unoszącego się nad głową gracza, gdy ten trzyma cel.
Tworzenie menedżera przechwytywania przedmiotów
- Utwórz nowe urządzenie Verse o nazwie item_capture_manager przy użyciu Eksploratora Verse i przeciągnij je do poziomu.
- U góry pliku
item_capture_manager:- Dodaj
using { /UnrealEngine.com/Temporary/SpatialMath }aby uzyskać dostęp do strukturyvector3. Wykorzystasz tę informację do ustalenia, gdzie teleportować wskaźniki unoszące się nad głową gracza. Dodaj takżeusing { /Fortnite.com/Characters }aby uzyskać dostęp dofort_charactergracza.using { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /Fortnite.com/Characters } using { /UnrealEngine.com/Temporary/Diagnostics } using { /UnrealEngine.com/Temporary/SpatialMath }
- Dodaj
- W definicji klasy
item_capture_managerdodaj następujące pola:- Edytowalna tablica urządzeń generatora przedmiotów do przechwycenia o nazwie
CaptureItemSpawners. Tablica ta zawiera urządzenie generatora przedmiotów do przechwycenia dla infiltratorów.item_capture_manager := class(creative_device): Logger:log = log{Channel := triad_item_capture_log_channel} # Generator przedmiotów do przechwycenia, który spawnuje przedmiot do przechwycenia. @editable CaptureItemSpawner:capture_item_spawner_device = capture_item_spawner_device{} - Edytowalny rekwizyt trybu kreatywnego o nazwie
CaptureItemIndicator. Rekwizyt ten będzie unosił się nad głową infiltratora, gdy ten chwyci cel.# Generator przedmiotów do przechwycenia, który spawnuje przedmiot do przechwycenia. @editable CaptureItemSpawner:capture_item_spawner_device = capture_item_spawner_device{} # Obiekt, który unosi się nad głową gracza, gdy trzyma on przedmiot z # CaptureItemSpawner. @editable CaptureItemIndicator:creative_prop = creative_prop{} - Edytowalne urządzenie znacznika na mapie o nazwie
MapIndicator. Będzie on znajdował się pod CaptureItemSpawner w poziomie i wyświetlał na mapie w miejscu, gdzie znajdują się cele dla każdej drużyny.# Obiekt, który unosi się nad głową gracza, gdy trzyma on przedmiot z # CaptureItemSpawner. @editable CaptureItemIndicator:creative_prop = creative_prop{} # Wskaźnik, który wyświetla, gdzie na mapie znajdują się cele dla każdej drużyny @editable MapIndicator:map_indicator_device = map_indicator_device{} - Dwie edytowalne wartości pojedynczej precyzji (float)
UpdateRateSecondsiVerticalOffset. Pierwsza z nich określa szybkość zmiany położenia rekwizytuCaptureItemIndicator, a druga definiuje odległość od głowy gracza, na jakiej unosić się będzie rekwizytCaptureItemIndicator.# Wskaźnik, który wyświetla, gdzie na mapie znajdują się cele dla każdej drużyny @editable MapIndicator:map_indicator_device = map_indicator_device{} # Określ, jak często CaptureItemIndicator aktualizuje swoją pozycję. @editable UpdateRateSeconds:float = 0.15 # Określ, jak wysoko nad głową gracza unosi się wskaźnik CaptureItemIndicator. @editable VerticalOffset:float = 180.0 - Edytowalne urządzenie komunikatów w interfejsie o nazwie
ItemGrabbedMessageDevice. Powoduje to wysłanie wiadomości do każdego gracza po podjęciu celu.# Określ, jak wysoko nad głową gracza unosi się wskaźnik CaptureItemIndicator. @editable VerticalOffset:float = 180.0 # Wyświetla komunikat, gdy gracz złapie przedmiot przechwytywania. @editable ItemGrabbedMessageDevice:hud_message_device = hud_message_device{} - Edytowalne urządzenie menedżera wyniku o nazwie
ScoreManagerDevice. To urządzenie przyznaje drużynie punkty za każdym razem, gdy gracz zdobędzie cel# Wyświetla komunikat, gdy gracz złapie przedmiot przechwytywania. @editable ItemGrabbedMessageDevice:hud_message_device = hud_message_device{} # Przyznaje punkty, gdy gracz zdobędzie przedmiot do przechwycenia. @editable ScoreManagerDevice:score_manager_device = score_manager_device{} - Edytowalna wartość pojedynczej precyzji (float) o nazwie
ReturnTime. Jeśli przedmiot do przechwycenia ma określony czas powrotu przed powrotem do CaptureItemSpawner, należy śledzić długość tego czasu powrotu, aby wiedzieć, kiedy zwrócić wskaźniki z powrotem do CaptureItemSpawner.
- Edytowalna tablica urządzeń generatora przedmiotów do przechwycenia o nazwie
- Dodaj nową metodę
FollowCharacter()do definicji klasyitem_capture_manager. Metoda ta pobiera obiektfort_characteri śledzi go, umieszczając nad jego głową wskaźnik. Dodaj specyfikator<suspends>do tej funkcji, ponieważ chcesz, aby funkcja ta była spawnowana dla gracza za każdym razem, gdy trzyma on cel.# Powoduje, że CaptureItemIndicator stale podąża za graczem nad jego głową. # Wykonuje wyrażenie race między pętlą aktualizacji dla CaptureItemIndictator, a tym, czy gracz # przechwyci przedmiot, upuści go, czy zostanie wyeliminowany. FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("Zespawnowano funkcję FollowCharacter")
Uruchamianie wyrażenia race, gdy gracz trzyma cel
Ważne, aby przemyśleć, co stanie się, gdy gracz chwyci cel. Gracz może:
- Poruszać się, a wówczas musisz stale aktualizować wskaźniki CaptureItem i Map zgodnie z pozycją gracza. Można do tego wykorzystać pętlę.
- Przechwycić cel, a wówczas wskaźniki muszą wrócić do CaptureItemSpawner gdzieś poza zasięgiem wzroku, ponieważ nie powinny być widoczne, chyba że gracz trzyma przechwycony przedmiot.
- Upuścić cel lub zostać wyeliminowanym, a wówczas wskaźniki muszą pozostać w miejscu, w którym przedmiot został upuszczony, i powrócić do CaptureItemSpawner, gdy przedmiot do przechwycenia powróci.
Aby uzyskać taki efekt, skonfigurujesz wyrażenie race. Stosując wyrażenie race między trzema powyższymi warunkami, możesz kontynuować aktualizowanie położenia wskaźnika, oczekując równocześnie, aż gracz upuści lub przechwyci cel.
- Dodaj wyrażenie
racedoFollowCharacter(). Skonfiguruj wyrażenie race do uruchomienia międzyloop,Await()dla zdarzeniaItemCapturedEventurządzeniaCaptureItemSpawner,Await()dla zdarzeniaItemCapturedDroppedEventurządzeniaCaptureItemSpawneraAwait()dla zdarzeniaEliminatedEvent()obiektuFortCharacter.FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("Zespawnowano funkcję FollowCharacter") race: loop: CaptureItemSpawner.ItemCapturedEvent.Await() CaptureItemSpawner.ItemDroppedEvent.Await() FortCharacter.EliminatedEvent().Await() - W wyrażeniu
looppobierz pozycjęFortCharacteri zapisz ją w zmiennejTransform.loop: Transform := FortCharacter.GetTransform() - Teraz zespawnuj
MoveTo(), aby przenieść zarównoCaptureItemIndicator, jak iMapIndicatorzgodnie z translacją i obrotem zmiennejTransform, z zastosowaniem skonfigurowanej wcześniej wartościVerticalOffsetprzez czasUpdateRateSeconds. Chcesz użyćSpawn{}dla obu funkcjiMoveTo(), ponieważ zarównoCaptureItemIndicatorjak iMapIndicatormuszą poruszyć się dokładnie w tym samym czasie, a nie czekać na zakończenie wyrażenia każdego z nich. Translacja to wartośćvector3złożona ze współrzędnychX,YiZ, więc trzeba wstawićVerticalOffsetdo nowegovector3. WartośćVerticalOffsetokreśla odległość w pionie nad głową gracza, więc ustaw ją jako wartośćZparametruvector3.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)} - Na koniec uśpij na
0,0sekund. Dzięki temu pętla zostanie wykonana tylko raz na aktualizację symulacji i nie wymknie się spod kontroli, spawnując funkcjeMoveTo(). Otrzymany kodFollowCharacter()powinien wyglądać następująco:# Powoduje, że CaptureItemIndicator stale podąża za graczem nad jego głową. # Wykonuje wyrażenie race między pętlą aktualizacji dla CaptureItemIndictator, a tym, czy gracz # przechwyci przedmiot, upuści go, czy zostanie wyeliminowany. FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("Zespawnowano funkcję FollowCharacter") 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)} # Chcemy mieć pewność, że pętla ta zostanie uruchomiona tylko raz na aktualizację symulacji, więc uśpimy ją na jedno tyknięcie gry. Sleep(0.0) CaptureItemSpawner.ItemCapturedEvent.Await() CaptureItemSpawner.ItemDroppedEvent.Await() FortCharacter.EliminatedEvent().Await() Logger.Print("Cel został upuszczony lub przechwycony")Resetowanie wskaźników
- Kiedy przedmiot do przechwycenia zostanie przechwycony lub zwrócony, musisz zwrócić wskaźniki do
CaptureItemSpawnergdzieś poza zasięgiem wzroku. W tym przypadku przeteleportujesz je wysoko ponadCaptureItemSpawner. W tym celu dodaj metodę o nazwieReturnIndicators()do definicji klasyitem_capture_manager.# Zwraca znacznik na mapie i wskaźnik przedmiotu do przechwycenia z powrotem do ich pozycji początkowych nad generatorami. ReturnIndicators(InAgent:agent):void= - Pobierz przekształcenie obiektu
CaptureItemSpawneri zapisz je w zmiennejSpawnerTransform. Następnie zespawnujMoveTo()dla obiektuCaptureItemIndicatoriMapIndicatordo przekształcenia i obrotu obiektuCaptureItemSpawner, dodając wartośćVerticalOffsetw taki sam sposób, jak w wyrażeniuloop, aby umieścić wskaźniki nadCaptuerItemSpawnwer. Jeśli chcesz, aby rekwizyt znalazł się daleko poza polem widzenia, możesz pomnożyć wartośćVerticalOffsetprzez dużą liczbę, w tym przypadku 10. Gotowy kod metodyReturnIndicators()powinien wyglądać następująco:# Zwraca znacznik na mapie i wskaźnik przedmiotu do przechwycenia z powrotem do ich pozycji początkowych nad generatorami. ReturnIndicators():void= SpawnerTransform := CaptureItemSpawner.GetTransform() # Teleportuj z powrotem do generatora, ukrywając CaptureItemIndicator i MapIndicator nad mapą, poza zasięgiem wzroku. 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("Zwrócono wskaźnik do generatora przedmiotów do przechwycenia")
Obsługa graczy chwytających, upuszczających i przechwytujących cel.
- Dodaj nową metodę
OnItemPickedUp()do definicji klasyitem_capture_manager. Metoda pobiera obiektagenti spawnuje instancjęFollowCharacter()dla tej postaci.# Informuj każdego gracza, gdy któryś gracz chwyci cel OnItemPickedUp(InAgent:agent):void= Logger.Print("Przechwycono cel") - Pobierz
FortCharacterdlaInAgenti zespawnuj funkcjęFollowCharacter()z użyciem pobranegoFortCharacter. Gotowy kod metodyOnItemPickedUp()powinien wyglądać następująco:# Informuj każdego gracza, gdy któryś gracz chwyci cel OnItemPickedUp(InAgent:agent):void= Logger.Print("Przechwycono cel") if(FortCharacter := InAgent.GetFortCharacter[]): ItemGrabbedMessageDevice.Show() spawn{FollowCharacter(FortCharacter)} - Dodaj nową metodę
OnItemCaptured()do definicji klasyitem_capture_manager. Ta metoda pobiera obiektagent, który zdobył cel.# Po przechwyceniu przedmiotu przyznaj punkty drużynie przechwytującej i zwróć wskaźniki. OnItemCaptured(CapturingAgent:agent):void= Logger.Print("Przechwycono cel") - W
OnItemCaptured()aktywujScoreManagerDevice, aby przyznać punkty drużynie gracza przechwytującego, i wywołajReturnIndicators(), aby zwrócić wskaźniki.# Po przechwyceniu przedmiotu przyznaj punkty drużynie przechwytującej i zwróć wskaźniki. OnItemCaptured(CapturingAgent:agent):void= Logger.Print("Przechwycono cel") ScoreManagerDevice.Activate() ReturnIndicators() - Dodaj nową metodę
OnItemDropped()do definicji klasyitem_capture_manager. Ta metoda pobiera obiektagent, który upuścił przedmiot.# Gdy gracz upuści przedmiot, uruchom funkcję WaitForReturn(), # jeśli wartość ReturnTime jest większa niż 0. OnItemDropped(InAgent:agent):void= Logger.Print("Upuszczono cel") - Gdy cel zostanie upuszczony, wskaźniki powinny pozostać w pobliżu celu, dopóki cel nie zostanie podniesiony lub nie powróci do
CaptureItemSpawner. Aby wiedzieć, kiedy zwrócić wskaźniki, użyjesz ustawionej wcześniej zmiennejReturnTime. Jeśli wartośćReturnTimejest większa lub równa0.0, chcesz odczekać ten czas, a następnie zwrócić wskaźniki. Jeśli wartośćReturnTimejest ujemna, cel nie ma określonego czasu powrotu, więc nie musisz przesuwać wskaźników. Aby przywrócić wskaźniki, uruchom nową funkcję pomocniczą o nazwieWaitForReturn(), którą zdefiniujesz w następnym kroku.# Gdy gracz upuści przedmiot, uruchom funkcję WaitForReturn(), # jeśli wartość ReturnTime jest większa niż 0. OnItemDropped(InAgent:agent):void= Logger.Print("Upuszczono cel") if(ReturnTime >= 0.0): spawn{WaitForReturn()} else: Logger.Print("Upuszczony cel nie wraca") - Dodaj nową metodę
WaitForReturn()do definicji klasyitem_capture_manager. Funkcja ta odczekuje czas określony wReturnTime, a następnie zwraca wskaźniki, jeśli cel nie został podniesiony przed upływem czasu oczekiwania. Dodaj modyfikator<suspends>do tej metody, aby umożliwić uruchamianie jej funkcjiSleep().# Odczekaj czas określony w ReturnTime, a następnie zwróć wskaźniki. WaitForReturn()<suspends>:void= Logger.Print("Oczekiwanie na powrót wskaźników...") - To, czy musisz zwrócić wskaźniki, zależy od tego, czy cel został podniesiony przed upływem czasu
ReturnTime. Jeśli tak, nie chcesz zwracać wskaźników, ponieważ natychmiast powróciłyby one do gracza, co mogłoby spowodować dziwne efekty wizualne. Aby rozwiązać ten problem, użyj zmiennej logicznej, której wartość jest równa wynikowi wyrażenia race.# Odczekaj czas określony w ReturnTime, a następnie zwróć wskaźniki. WaitForReturn()<suspends>:void= Logger.Print("Oczekiwanie na powrót wskaźników...") # Zwróć wskaźniki CaptureItem i Map, jeśli przedmiot do przechwycenia # nie zostanie podniesiony przed upływem czasu. ShouldReturn:logic := race: - Funkcja
WaitForReturn()musi wykonać wyrażenie race między dwoma warunkami. Kończy się czasReturnTimei cel powraca doCaptureItemSpawner, w którym to przypadku wskaźniki muszą wrócić, aShouldReturnpowinno mieć wartośćtrue. Albo cel zostanie podniesiony przed upływem czasuReturnTime, w którym to przypadkuShouldReturnpowinno mieć wartośćfalse. Ponieważ każdy z tych warunków zwraca wartość, wyrażenie race zostanie uruchomione przy użyciu dwóch oddzielnychblocks.ShouldReturn:logic := race: block: block: - W pierwszym bloku wywołaj
Sleep()na czasReturnTime, a następnie zwróćtrue. W drugim bloku wykonajAwait()dlaCaptureItemSpawner.ItemPickedUpEventi zwróć false. ZmiennaShouldReturnzostanie teraz zainicjowana na tę z funkcji, która zostanie ukończona jako pierwsza.ShouldReturn:logic := race: block: Sleep(ReturnTime) true block: CaptureItemSpawner.ItemPickedUpEvent.Await() false - Jeśli
ShouldReturnma wartość true, musisz zwrócić wskaźniki. WywołajReturnIndicators(), jeśliShouldReturnzwraca wartośćtrue. Kompletny kodWaitForReturn()powinien wyglądać następująco:# Odczekaj czas określony w ReturnTime, a następnie zwróć wskaźniki. WaitForReturn()<suspends>:void= Logger.Print("Oczekiwanie na powrót wskaźników...") # Zwróć wskaźniki CaptureItem i Map, jeśli przedmiot do przechwycenia # nie zostanie podniesiony przed upływem czasu. ShouldReturn:logic := race: block: Sleep(ReturnTime) true block: CaptureItemSpawner.ItemPickedUpEvent.Await() false if(ShouldReturn?): ReturnIndicators() - Teraz w
OnBegin()zasubskrybuj zdarzenieItemPickedUpEventurządzeniaCaptureItemSpawnerdoOnItemPickedUp(), zdarzenieItemCapturedEventdoOnItemCaptured(), a zdarzenieItemDroppedEventdoOnItemDropped().OnBegin<override>()<suspends>:void= CaptureItemSpawner.ItemPickedUpEvent.Subscribe(OnItemPickedUp) CaptureItemSpawner.ItemCapturedEvent.Subscribe(OnItemCaptured) CaptureItemSpawner.ItemDroppedEvent.Subscribe(OnItemDropped) SpawnerTransform := CaptureItemSpawner.GetTransform() - Na końcu w
OnBegin()ustaw wskaźniki w ich położeniu początkowym, gdy skrypt zostanie uruchomiony, wywołującMoveTo()wCaptureItemIndicatoriMapIndicator. Kod metodyOnBegin()powinien wyglądać następująco:OnBegin<override>()<suspends>:void= CaptureItemSpawner.ItemPickedUpEvent.Subscribe(OnItemPickedUp) CaptureItemSpawner.ItemCapturedEvent.Subscribe(OnItemCaptured) CaptureItemSpawner.ItemDroppedEvent.Subscribe(OnItemDropped) SpawnerTransform := CaptureItemSpawner.GetTransform() # Teleportuj z powrotem do generatora, ukrywając CaptureItemIndicator pod mapą, poza zasięgiem wzroku. CaptureItemIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds) MapIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds) -
Wróć do edytora, zapisz skrypt, skompiluj go i przeciągnij urządzenie do poziomu. Wybierz odpowiedni rekwizyt, który ma pełnić funkcję wskaźnika
CaptureItemIndicatorw twoim poziomie. Możesz użyć dowolnego rekwizytu, pod warunkiem że będzie on dostatecznie widoczny. W tym przykładzie użyjesz Diamentu. W panelu Szczegóły przypisz CaptureItemSpawner do InfiltratorCaptureSpawner oraz CaptureItemIndicator do wybranego rekwizytu. Przypisz również MapIndicator do znacznika na mapie infiltratorów, ItemGrabbedMessageDevice do urządzenia komunikatu w interfejsie infiltratorów, a ScoreManagerDevice do menedżera wyniku infiltratorów. Ustaw ReturnTime na liczbę ujemną, ponieważ przedmiot przechwycony przez infiltratora nie wraca.Warto również skonfigurować instancję
item_capture_managerdla atakujących. Pamiętaj, aby zmienić CaptureItemIndicator na rekwizyt różny od rekwizytów stosowanych w przypadku infiltratorów, co pozwoli uniknąć wątpliwości w drużynach, i upewnij się, że zostały przypisane wszystkie inne urządzenia. Ustaw ReturnTime na liczbę dodatnią, ponieważ przedmiot przechwycony przez atakujących wraca po ustawionym czasie. - Na pasku narzędzi UEFN kliknij Uruchom sesję, aby przetestować poziom w grze. Podczas testowania poziomu w grze nad głową gracza, który chwyci cel powinien znajdować się rekwizyt. Rekwizyt powinien poruszać się razem z graczem, a gdy gracz upuści lub przechwyci cel, rekwizyt powinien teleportować się z powrotem do generatora przedmiotów do przechwycenia.

Następny krok
W następnym kroku tego samouczka dowiesz się, jak szybko przekazać graczom instrukcje dotyczące gry, oraz poznasz obszary, na których warto się skoncentrować przy udoskonalaniu przygód dla graczy.