Wspierające systemy

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

Użyliśmy następujących systemów do wsparcia zarówno systemów gry podstawowej, jak i wszelkich celów wymagań głównego projektu .

Użyj menedżera

UseManager dostarczył prostą API do zastosowania chwyconego obiektu na coś, takiego jak kawałek ubrania na manekinie.Główną funkcją dla tego API jest UseManager.AddUse (tagi, obiekty docelowe, odległość, na powodzenie, na nic nie wyposażone, na błędnie wyposażone, dodatkowe dane), które wiąże zestaw tagów do obiektów docelowych .Gdy gracz ma obiekt z jedną z tagów i kliknie na celowy obiekt, funkcja powrotu onSuccess jest wywoływana.Inne funkcje wezwania pozwoliły nam pokazać graczom dodatkowe informacje wizualne, jeśli kliknięcie zostanie wykonane bez chwytanego przedmiotu lub z błędnym rodzajem przedmiotu.

Moglibyśmy usunąć "użycie" za pomocą UseManager.RemoveUse, które zwykle było pomocne, gdy misja została zakończona lub określony przedmiot został "użyty".Ponadto możemy dodać lub usunąć cele za pomocą AddUseTargets i RemoveUseTargets.

Podświetlenia

Kiedy gracz był w pobliżu przedmiotu zainteresowania, takiego jak foka, chcieliśmy, aby ten przedmiot wyróżniał się od otoczenia.Aby to zrealizować, stworzyliśmy LocalScript o nazwie Podświetlone elementy , które wykorzystują kulę skupioną wokół gracza, aby wykrywać dotknięcia za pomocą innych siatek, łącząc się z wydarzeniami Touched i TouchEnded.Funkcja getHighlight sprawdza kilka tagów na dotkniętej siatce lub jej rodzicach za pomocą funkcji pomocniczej GetTaggedObjectUpHierarchy .Jeśli żadne podświetlenie nie jest potrzebne, możemy wymusić jego usunięcie za pomocą tagu Nie podświetlaj .Jeśli jednak jest potrzebny, ale nie pasuje do różnych innych tagów, możemy go wymusić za pomocą tagu Ważne .

Ta LocalScript korzysta z nowej funkcji silnika Highlight, która rysuje kontur obiektu i/lub wypełnia wnętrze obiektu określoną kolor; dla więcej informacji o tym, jak korzystać z tej funkcja, patrz Podświetlanie obiektów.Highlights i myszowa kursor OnItemIndicator systemy współpracują ze sobą, więc Highlights nie tylko określają, czy siatka potrzebuje podświetlenia, ale dostarczają również rodzaj siatki dla OnItemIndicator .

HighlightItemsFunc jest używany do komunikacji z innymi systemami klientów.Na przykład EventManager używa go za pomocą polecenia Włącz w celu włączenia lub wyłączenia Highlight w niektórych scenach cięcia, a Indykator przedmiotu używa GetType do zapytania o rodzaj obiektu.Aby wykryć, kiedy przedmiot nie jest już obecny, na przykład kiedy zniszczono skorumpowany pokój, łączymy się z CollectionService.GetInstanceRemovedSignal.

Historia i myślowe bąbelki

Lore i Bąbelki myśli to 2 podobne systemy.Lore używa ScreenGui jako kontenera interfejsu użytkownika na ekranie z dzieckiem Frame do kontroli rozmiaru i przesuwania swoich dzieci TextLabels i ImageLabels , a Lore czeka, aż gracz kliknie gdziekolwiek na ekranie, aby go usunąć.Podobnie, bąbelki myśli używają BillboardGui z dzieckiem TextLabel do obiektów niezwiązanych z historią, a wyświetla dialog w przestrzeni 3D w pobliżu obiektu przez określony czas i okres odnowienia bez zajmowania całego ekranu przez tekst.Aby uzyskać więcej informacji o projektowaniu za tymi systemami, zobacz Lore i Thought Bubbles.

Lore jest wdrożony w LoreManger LocalScript .Kiedy kliknięto lub dotknięto, uruchamia promieniowanie za pomocą funkcji pomocniczej utils.RaycastAlongPointingDir i używa grupa Niezderzanie gracza .Jeśli siatka pod kliknięciem lub jeden z rodziców ma tag Lore lub ThoughtBubble , wyświetlamy interfejs użytkownika.Tekst, napis i obraz są określone przez atrybuty LoreText, LoreCaption i LoreImage na obiekcie.

Zauważ, że używamy Camera.ViewportPointToRay lub Camera.ScreenPointToRay do konstrukcji promienia, w zależności od tego, czy został wezwany z nie dotykowego lub dotykowego.Koordynaty są w nieco różnych systemach koordynatów.Dla myszy otrzymujemy je z Class.UserInputService.InputEnded``:Connect dla MouseButton1, a dla urządzeń dotykowych otrzymujemy je z Class.UserInputService.TouchTapInWorld``:Connect.

Bąbelki myśli są ogólnie podobne, wykorzystując raycast, aby sprawdzić, czy siatka lub jej rodzice mają tag Bąbelka myśli .Używa również atrybutu ThoughtText dla tekstu oraz tagu ThoughtBubble do wskazania obiektu placeholder używanego do pozycjonowania interfejsu w świecie.Bąbelki myśli, które używają tego samego obiektu pozycyjnego, ale mają różny tekst, mają różne odnowienia.

Specjalne przypadki

Lore ma kilka specjalnych przypadków, jednym z nich są skorumpowane foki.Kiedy gracz kliknie uszkodzone pieczęcie, wyświetla interfejs użytkownika wiedzy i czeka na kliknięcie, aby rozpocząć misję, która wpływa na przepływ gry.Jest to obsługiwane przez GameStateClient korzystające z wiązalnego LoreManagerFunc w celu żądania interfejsu użytkownika lore.Wezwanie jest dostarczane do systemu Lore przez GameStateClient, aby wiedzieć, kiedy lore zostanie "zamknięte" przez gracza.Innym specjalnym przypadkiem jest sytuacja, gdy tagi Bąbelki myśli i Wiedza są na tym samym obiekcie.W tym przypadku, aby uniknąć pokrycia tekstu bąbelka wiedzy i myśli, uruchamiamy bąbelkę myśli po zamknięciu wiedzy. LoreManager również obsługuje specjalny przypadek, pokazując małą scenkę, gdy klikniesz na wyłączone drzwi, które są zamknięte, dopóki gracz nie odbierze pieczęci pokoju.

Wskaźnik przedmiotu OnItemIndicator

Chcemy pokazać różne ikony w centrum ekranu, gdy gracz patrzy na określone przedmioty zainteresowania.Skrypt klienta OnItemindicator wykonuje rzut promieni wzdłuż kamery Class.CFrame.LookVector i analizuje wyniki.Na podstawie wyników ustawia obraz w OnItemIndicator2 ScreenGui .

Gdy nie trafiono żadnych przedmiotów zainteresowania, domyślnym ikoną jest mały punkt.Moglibyśmy ustawić dowolną ikonę, dodając atrybut OnItemIndicator do konkretnej siatki, używając nazw z onItemIndicatorImages, takich jak Ręka, Oko lub DrzwiObecnieZablokowane.Atrybut jest potrzebny tylko w rzadkich przypadkach, a większość czasu inne istniejące tagi lub systemy dostarczają rodzaj ikona.Dla więcej szczegółów zobacz funkcję Update .

Typowe kontrolki sprawdzają niektóre w kolejności priorytetowej.Po przeładowaniu OnItemIndicator sprawdzamy, czy jest dostępny lub szuflada dla ikony "ręka" za pomocą utils.CanGrabModel(model) lub utils.GetTaggedObjectUpHierarchy("Drawer2", model) .Następnie wywołujemy HighlightManager, które określa status podświetlenia, rodzaje elementów i ikony, które należy użyć.Na przykład:


highlightItemsFunc:Invoke({"GetType", curInst})

Tagi Lore i ThoughtBubble są sprawdzane później poprzez sprawdzanie tagów.Dla drzwi mamy 2 różne ikony: Drzwi obecnie zamknięte i Drzwi zawsze zamknięte .DoorManager ustawia prawdziwą lub fałszową atrybut DoorEnabled dla drzwi, które mogą być otwarte lub zamknięte, i używamy obecności i wartości atrybutu.Obiekty, które wyglądają jak drzwi, ale nie otwierają się, mają tag Drzwi zamknięte .

Menadżer drzwi

Menadżer drzwi używa tagu drzwi i zamyka drzwi do zarządzania otwieraniem i zamykaniem drzwi.Drzwi mają przednią i tylną stronę spustów, które łączymy z dotykiem i wydarzeniami touchEnded.Stworzyliśmy nastolatków, aby otwierać i zamykać drzwi z przodu i z tyłu.Mamy utrzymujemy mapę graczyNear (z graczami dotykającymi spustów, oddzielnie dla przodu i tyłu.

Każde drzwi ma prosty system stanu, DoorState (Zamknięte, Otwieranie, Otwórz, Zamknij), z nastolatkami używanymi do przejść.Możemy włączyć lub wyłączyć zdolność otwierania lub zamykania drzwi z systemów zewnętrznych, wywołując DoorManager.EnableDoor, które ustawia atrybut DoorEnabled.

Mistrz animator

The MasterAnimator LocalScript odtwarza animowane obrazy (atlas tekstur), których używaliśmy do animowania ekranów telewizyjnych.Aby przewijać obrazy, musieliśmy znać zestaw parametrów: liczbę rzędów i kolumn, liczbę całych ram, periody, wymiary obrazów i zestaw ID obrazów.System pozwolił nam animować na wielu obrazach, każdy z nich może być podzielony na rzędy i kolumny podobnych obrazów.Moglibyśmy przekazać te dane za pomocą atrybutów lub wartości, ale w tym doświadczeniu użyliśmy skryptów pomocniczych.UpdateImageAnimations(dT) oblicza, jaką obraz lub podobrazie musieliśmy pokazać za pomocą czasu i parametrów.Jeśli musieliśmy zmienić na nowy obraz, ustawiliśmy obraz.Jeśli musimy zmienić jakikolwiek podobraz, ustawiamy ImageRectOffset.

Obiekt z animowanym SurfaceGui będzie miał animatora ModuleScript, głównym celem którego jest zapewnienie funkcji Animator.GetParams, która zwraca wszystkie parametry.Pomaga to MasterAnimatorowi LocalScript, który używa tagu Animacja obrazu i CollectionService gromadzi takie obiekty oraz znajduje Animatora ModuleScript pod nimi.Następnie używa pcall, aby wymagać Animatora ModuleScript i wezwać GetParams na nim.

Animacje lokalnej przestrzeni

Lokalna animacja przestrzeni używa tagu Lokalna rotacja przestrzeni, aby obrócić głównie obiekty "kosmetyczne" z daną prędkością obrotową i opóźnieniem wokół osi X, Y lub Z.Użyliśmy tego do odległych obiektów, z którymi gracze nie będą interakcjonować, lub do mniejszych obiektów, które nie wpływają na symulację wiele.Parametry określone za pomocą wartości Speed, Delay i Axis.Dla szczegółów wdrożenia patrz Obrocone chmurkowe siatki.

Menadżer latarki

Menadżer lampki głownej obsługuje sytuacje, w których użytkownicy wybierają lampkę na ekranie , aby przełączyć reflektor nad ich głową włączony lub wyłączone, wysyła komentarze do serwera za pomocą wydarzenia lampki głownej i przełącza dźwięki włączania i wyłączania.Kiedy dodano postać lub zmieniono jej zmieniono lampę funkcja klonuje lampę używając niektórych przesunięć i rotacji z FaceFrontAttachment .

Menadżer siedzeń

Nie chcemy, aby gracze automatycznie siedzieli, gdy są w pobliżu obiektu, na którym mogą usiąść.Zamiast tego chcemy wymagać od użytkowników, aby kliknęli w pobliżu siedzenia, aby usiąść.Skrypt SeatManager dodaje ClickDetectors w oparciu o tag Siedzenie i dzwoni seat:Sit(humanoid) po kliknięciu.Podczas teleportowania graczy między normalnym a skorumpowanym stanem pokoju nie możemy mieć siedzących graczy, ponieważ zmiana koordynatów CFrame nie będzie w stanie działać, więc Menadżer siedzeń ma funkcjonalność dezaktywowania lub włączania siedzenia kilka sekund przed i po teleportować się.

Menadżer szufli

Skrypt DrawerManager używa tagu Drawer2 i CollectionService do obsługi kliknięcia na szuflady, aby otworzyć je lub zamknąć, i odtworzyć odpowiednią dźwięk.Akcja otwierania i zamykania jest wykonywana poprzez ustawienie TargetPosition dla PrismaticConstraint .

Objętości zabójstwa

W kilku obszarach głównej strefy rozgrywki, takich jak elektryczne iskry i woda w pobliżu początku drogi prowadzącej do domu, gracz może ustawić swój Humanoid.Health na 0, wchodząc do głośności z tagiem KillVolume .Skrypt KillVolumes używa Touched:Connect , aby określić, kiedy gracz wchodzi do wolumenu, a następnie zmniejsza jego zdrowie do 0 .

Odrodzenie misji gracza

Skrypt PlayerMissionRespawn używa tagu RespawnVolume i CollectionService, aby radzić sobie z objętościami, które sprawiają, że gracze odrodzą się, gdy zostaną dotknięci.Umieściliśmy te objętości pod pokojami korumpowanymi, ponieważ wiele misji ma luki lub poruszające się platformy, na których gracz mógłby upaść.Po dotknięciu skrypt odtwarza małą scenę Teleport_Jump i wzywa za pomocą komendy.

Podczas przetwarzania GameEvents.PlayerRespawn, skrypt może używać RespawnPositions, jeśli konfiguracja misji zapewnia to.Jeśli nie, używa TeleportPositions na specyficzną misję.Nie mamy systemu "punktów kontrolnych", więc CalcClosestTeleportPos po prostu wybiera najbliższe Respawn lub Teleport miejsca, z których gracz uderzył w RespawnVolume, używając jedynego poziomego, "2D" dystansu.

Małe systemy pomocnicze

Menadżer pianina

Skrypt PianoManager używa tagu Piano i CollectionService dodaje ClickDetectors i odtwarza jeden z dźwięków pianina, gdy kliknięto na klawiaturze.

Wsparcie rytualne

Foyer, w którym gracze umieszczają pieczęcie, ma skomplikowaną konstrukcję, która przechodzi zmiany, gdy każda pieczęć jest umieszczana w określonej lokalizacji.Na przykład, w zależności od liczby umieszczonych fok, konkretne wydarzenia odtwarzają, aby włączyć/wyłączyć światła i promienie, zmienić przejrzystość pewnych obiektów itp.Wsparcie rytuałowe RitualSupport ModuleScript jest małym wrapperem nad EventManager:Invoke wezwania dla tych wydarzeń, zapewniając parametry dla wydarzenia, takie jak to, na którym ma zagrać "korzenny obiekt", w zależności od tego, jaki szczególny pieczątek został umieszczony.

Menadżer do odtworzenia

Niektóre chwytywalne obiekty są ważne dla rozgrywka, takie jak foki, i nie chcieliśmy, aby się zgubiły, jeśli gracz je gdzieś upuścił.Jeśli obiekt ma tag Przywracalny , skrypt PrzywracalnyMenadżer zapamiętuje jego transformację, gdy zostanie dodany do systemu przywracalnego.Kiedy gracz upuszcza taki przedmiot, system chwytania dzwoni restorableManager.StartTracking .Jeśli obiekt nie zostanie ponownie odebrany za pięć sekund, skrypt Menadżera do odzyskiwania umieszcza go w oryginalnej transformacji i zmienia czas śledzenia.

Portały

W kilku misjach teleportujemy graczy na krótki dystans w ramach misji, takich jak odrodzenie graczy, którzy spadają z obracającej się platforma.Aby uprościć konfigurację tego typu teleportacji, które nazywamy "portalami" w skrypcie, używa się funkcji pomocniczej ProcessPortal w DemoUtils .Na przykład, jeśli P1 jest częścią definiującą początkowy trigger, a P2 jest częścią definiującą transformację gracza docelowego, następujący kodowy snippet może zdefiniować taką funkcjonalność portalu:


P1.Touched:Connect(function(otherPart) utils.ProcessPortal(otherPart, P2) end)

Portal procesowy zajmuje się sprawdzaniem, czy inna część jest człowiekiem, teleportuje gracza za pomocą zmiany koordynaty CFrame i wywołuje małą scenkę, aby ukryć przejście za pomocą wydarzenia Teleport_Jump w Menadżerze wydarzeń.

Skrypty konfiguracyjne

Mamy kilka konfiguracji, definicji danych i wspólnych skryptów funkcjonalnych: DemoConfig . Definicje misji. Enumeracje dla stanów gry, wydarzenia dla komunikacji klient-serwer. DemoGlobalSettings .Rozwijamy się w jednym miejscu, ale uwalniamy (i testujemy) w innych.Skrypt sprawdza miejsceID i umożliwia/wyłącza różne oszustwa i funkcje debugowania. DemoUtils .Różne funkcje użytkowe.Radzenie sobie z transformacjami.Ustawianie widoczności, zakotwiczone lub inne właściwości.Sprawdzanie punktu w pudełku.Wyszukiwanie obiektów w hierarchii za pomocą nazwy "przekropionej".Zarządzanie TempStorage (które można wykorzystać do tymczasowego przesuwania modeli "w jakimś dalekim miejscu" i przywracania ich później).Kliknij pomocników wykrywaczy.Pobieranie wsparcia.Wsparcie dla sprawdzania tagów (szczególnie w hierarchii).Łączenie triggerów z Menadżerem wydarzeń. AudioUtils . Kilka funkcji do odtwarzania wagowanych losowych dźwięków z ustawiać. GrabUtil . Funkcje pomocnicze do chwytania.