Unterstützte Systeme

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

Wir verwendeten die folgenden Systeme, um sowohl die grundlegenden Spielsysteme als auch alle Ziele der Hauptdesignanforderungen zu unterstützen.

VerwendeManager

UseManager bietet eine einfache API, um ein gefangenes Objekt auf etwas anzuwenden, wie ein Stück Schichtkleidung auf ein Mannequin.Die Hauptfunktion für diese API ist UseManager.AddUse (Tags, Zielobjekte, Distanz, auf Erfolg, auf NothingEquipped, auf WrongEquipped, zusätzliche Daten), die eine Reihe von Tags mit Zielobjekten verbindet.Wenn ein Spieler ein Objekt mit einem der Tags hat und auf ein Zielobjekt klickt, wird die onSuccess-Callback-Funktion aufgerufen.Andere Anruffunktionen ermöglichten es uns, Spielern zusätzliche visuelle Informationen anzuzeigen, wenn entweder ein Klick ohne ein mitgenommenes Element oder mit der falschen Artikelart erfolgt.

Wir könnten das "Verwenden" mit UseManager.RemoveUse entfernen, was normalerweise hilfreich war, wenn eine Mission abgeschlossen war oder ein bestimmtes Element "benutzt" wurde.Darüber hinaus könnten wir Ziele mit AddUseTargets und RemoveUseTargets hinzufügen oder entfernen.

Hervorhebungen

Wenn ein Spieler in der Nähe eines interessanten Gegenstands war, wie zum Beispiel einer Seepockung, wollten wir, dass dieser Gegenstand von seiner Umgebung herausragt.Um dies zu implementieren, haben wir ein LocalScript genanntes HighlightItems , das eine Kugel verwendet, die sich um den Spieler dreht, um Berührungen mit anderen Meshes zu erkennen, die sich mit Touched und TouchEnded Ereignissen verbinden.Die getHighlight Funktion prüft mehrere Tags auf einem berührten Meshes oder seinen Eltern mit einer GetTaggedObjectUpHierarchy Hilfsfunktion.Wenn keine Markierung nicht benötigt wird, könnten wir sie mit einem KeinHighlight -Tag zwangsweise entfernen.Wenn es jedoch benötigt wird, aber nicht ganz auf verschiedene andere Tags passt, könnten wir es mit dem Wichtigen -Tag erzwingen.

Diese LocalScript nutzt eine neue Engine-Funktion Highlight, die einen Umriss eines Objekts zeichnet und/oder das Innere des Objekts mit einer definierten Farbe füllt; für weitere Informationen darüber, wie diese Funktion verwendet wird, siehe Hervorhebung von Objekten. Highlights und der Mauszeiger OnItemIndicator arbeiten zusammen, so Highlights bestimmt nicht nur, ob ein Mesh ein Highlight benötigt, sondern bietet auch eine Art von Mesh für OnItemIndicator .

HighlightItemsFunc wird verwendet, um mit anderen Client-Systemen zu kommunizieren.Zum Beispiel verwendet EventManager es mit einem Aktivieren -Befehl, um ein Highlight zu aktivieren oder zu deaktivieren, und OnItemIndicator verwendet GetType, um nach der Art des Objekts zu fragen, die es ist.Um zu erkennen, wann ein Element nicht mehr vorhanden ist, wie z. B. wenn ein beschädigter Raum zerstört wird, verbinden wir uns mit CollectionService.GetInstanceRemovedSignal.

Überlieferung und Gedankenblasen

Lore und ThoughtBubbles sind 2 ähnliche Systeme.Lore verwendet eine ScreenGui als On-Screen-UI-Container mit einem Kind Frame , um die Größe und Skalierung seiner Kinder TextLabels und ImageLabels zu steuern, und Lore wartet, bis der Spieler irgendwo auf dem Bildschirm klickt, um es zu entfernen.Ebenso verwenden Gedankenblasen ein BillboardGui mit einem Kind TextLabel an nicht-lore-Objekten und zeigen Dialoge im 3D-Raum in der Nähe des Objekts für eine bestimmte Dauer und Abklingzeit ohne dass der Text die gesamte Bildschirmfläche einnimmt.Für weitere Informationen zum Design hinter diesen Systemen siehe Lore und Thought Bubbles.

Lore wird im LoreManger implementiert LocalScript.Wenn geklickt oder berührt wird, feuert es einen Strahlenstrahl mit einer Hilfsfunktion utils.RaycastAlongPointingDir ab und verwendet eine NoPlayerCollision Gruppe.Wenn ein Mesh unter dem Klick oder einer der Eltern ein Lore oder ThoughtBubble -Tag hat, zeigen wir die UI an.Der Text, die Untertitel und das Bild werden durch die LoreText-, LoreCaption- und LoreImage-Attribute auf dem Objekt definiert.

Beachten Sie, dass wir Camera.ViewportPointToRay oder Camera.ScreenPointToRay verwenden, um den Strahl zu konstruieren, abhängig davon, ob er von einem Nicht-Touch oder Touch aufgerufen wurde.Die Koordinaten sind in etwas verschiedenen Koordinatensystemen.Für die Maus erhalten wir sie von Class.UserInputService.InputEnded``:Connect für die MouseButton1, und für Touch-Geräte erhalten wir sie von Class.UserInputService.TouchTapInWorld``:Connect.

Gedankenblasen sind im Allgemeinen ähnlich, verwenden einen Raycast, um zu überprüfen, ob ein Mesh oder seine Eltern einen Gedankenblasen-Tag haben.Es verwendet auch den Attribut-ThoughtText für Text und einen ThoughtBubble -Tag, um auf ein Platzhalter-Objekt zu zeigen, das zur Platzierung der UI in der Welt verwendet wird.Gedankenblasen, die dasselbe positäre Objekt verwenden, aber unterschiedlichen Text haben, haben unterschiedliche Abklingzeiten.

Besondere Fälle

Lore hat ein paar Sonderfälle, einer davon sind die korrupten Seelen.Wenn ein Spieler auf ein beschädigtes Siegel klickt, wird die Lore-Benutzeroberfläche angezeigt, und er wartet auf einen Klick, um eine Mission zu starten, die den Spielablauf beeinflusst.Das wird von der GameStateClient verwaltet, die eine bindbare LoreManagerFunc verwendet, um Lore-Benutzeroberfläche anzufordern.Ein Rückruf wird dem Lore-System von GameStateClient bereitgestellt, um zu wissen, wann Lore vom Spieler:in"geschlossen" wird.Ein weiterer besonderer Fall ist, wenn Gedankenblasen und Überlieferung -Tags auf demselben Objekt sind.In diesem Fall, um eine Überschneidung von Märchen- und Gedankenblasentext zu vermeiden, führen wir die Gedankenblase aus, nachdem der Märchentext geschlossen ist. LoreManager behandelt auch einen besonderen Fall mit der Anzeige einer kleinen Szenenaufnahme, wenn auf deaktivierte Türen geklickt wird, die bis der Spieler das Siegel des Raums aufnimmt, verschlossen sind.

AufItemIndikator

Wir möchten verschiedene Ikonen in der Mitte des Bildschirms anzeigen, wenn der Spieler auf bestimmte interessante Elemente schaut.Das Client-Skript OnItemindicator führt einen Rayschuss entlang der Kamera Class.CFrame.LookVector und analysiert die Ergebnisse.Basierend auf den Ergebnissen legt es ein Bild im OnItemIndicator2 ScreenGui fest.

Wenn keine Artikel von Interesse getroffen werden, ist das Standard-Symbol ein kleiner Punkt.Wir könnten jedes Symbol festlegen, indem wir einem bestimmten Mesh einen OnItemIndicator Zeichenstring-Attribut hinzufügen, mit den Namen von onItemIndicatorImages, wie z. B. Hand, Auge oder DoorCurrentlyLocked.Das Attribut wird nur in seltenen Fällen benötigt, und die meiste Zeit stellen andere vorhandene Tags oder Systeme die Art des Symbols bereit.Für weitere Details siehe die Update Funktion.

Typprüfungen einige in einer Prioritäts顺序.Nach der überschreiben, überprüfen wir, ob es greifbar oder ein Schublade für das "Hand"-Symbol durch entweder utils.CanGrabModel(model) oder utils.GetTaggedObjectUpHierarchy("Drawer2", model) ist.Danach rufen wir HighlightManager auf, die den Highlight-Status, die Arten von Elementen und die zu verwendende Ikone bestimmt.Zum Beispiel:


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

Die Lore- und ThoughtBubble-Tags werden später überprüft, indem Tags überprüft werden.Für die Türen haben wir 2 verschiedene Ikonen: TürDerzeitGeschlossen und TürImmerGesperrt . DoorManager setzt ein echtes oder falsches DoorEnabled Attribut für Türen, die geöffnet oder geschlossen werden können, und wir verwenden die Präsenz und den Wert des Attributes.Objekte, die wie Türen aussehen, aber nicht geöffnet werden, haben das DoorLocked Tag.

Türmanager

Der DoorManager verwendet ein Tür-Tag und um Öffnungs- und Schließtüren zu verwalten.Die Tür hat Vorder- und Rückseiten-Trigger, die wir mit Berührung und touchEnded-Ereignissen verbinden.Wir haben Teenager erstellt, um eine Tür von der Vorder- und Rückseite zu öffnen und zu schließen.Wir unterhalten eine Spielernähe-Karte (von Spielern, die die Auslöser berühren, getrennt für die Vorder- und Rückseite.

Jede Tür hat ein einfaches Zustandssystem, DoorState (Geschlossen, Öffnen, Öffnen, Schließen), mit Teenagern, die für Übergänge verwendet werden.Wir könnten die Fähigkeit einer Tür aktivieren oder deaktivieren, von externen Systemen geöffnet oder geschlossen zu werden, indem wir DoorManager.EnableDoor anrufen, das ein DoorEnabled Attribut festlegt.

Meisteranimator

Der Masteranimator spielt animierte Bilder (Texturen-Atlas), die wir verwendet haben, um TV-Bildschirme zu animieren.Um durch Bilder zu scrollen, mussten wir eine Reihe von Parametern kennen: Anzahl von Zeilen und Spalten, Gesamtanzahl von Frames, Perios, Bildgrößen und eine Reihe von Bild-IDs.Das System ermöglichte es uns, über mehrere Bilder zu animieren, jedes möglicherweise in Reihen und Spalten von Unterbildern aufzuteilen.Wir könnten diese Daten über Attribute oder Werte bereitstellen, aber in dieser Erlebnisverwendeten wir Hilfsskripte. UpdateImageAnimations(dT) berechnet, welches Bild oder Unterbild wir benötigten, um es mit Zeit und Parametern anzuzeigen.Wenn wir zu einem neuen Bild wechseln mussten, setzten wir Image.Wenn wir ein Subbild ändern müssen, setzen wir ImageRectOffset .

Ein Objekt mit einer animierten SurfaceGui würde einen Animator ModuleScript haben, mit dem Hauptzweck, eine Animator.GetParams Funktion bereitzustellen, die alle Parameter zurückgibt.Dies hilft dem MasterAnimator LocalScript, der den Bildanimation -Tag und CollectionService verwendet, solche Objekte zu sammeln und den Animator ModuleScript unter ihnen zu finden.Dann verwendet es pcall, um Animator ModuleScript zu erfordern, und ruft GetParams darauf an.

Lokale Raumanimationen

Die Lokalen Raumanimationen verwendet ein LocalSpaceRotation-Tag, um hauptsächlich "kosmetische" Objekte mit einer angegebenen Rotationsgeschwindigkeit und Verzögerung um die Achsen X, Y oder Z zu drehen.Wir verwendeten dies entweder für entfernte Objekte, mit denen Spieler nicht interagieren würden, oder für kleinere Objekte, die die Simulation kaum beeinflussen. Parameter, die durch die Speed , Delay und Axis Werte definiert wurden.Für Details zur Umsetzung siehe Drehende Cloud-Meshes.

Kopf lampenmanager

Der HeadlampManager behandelt, wenn Benutzer die auf dem Bildschirm angezeigte Ausschalten auswählen, um den Scheinwerfer oben über ihrem Kopf ein- oder auszuschalten, sendet Kommentare zum Server mit HeadlampEvent und schaltet Tasten ein und aus.Wenn ein Charakter hinzugefügt oder seine Head geändert wird, klont die giveCharacterHeadlamp -Funktion die Vorlagenlampe und positioniert die Lampe mit einigen Verschiebungen und Rotationen aus der Gesichtsfront-Anbringung .

Sitzmanager

Wir möchten nicht, dass Spieler automatisch sitzen, wenn sie in der Nähe eines Objekts sitzen können.Stattdessen möchten wir, dass Benutzer in der Nähe eines Sitzes klicken, um sich zu setzen.Das Sitzmanager -Skript fügt ClickDetectors basierend auf einem Sitz -Tag hinzu und ruft seat:Sit(humanoid) an, wenn es angeklickt wird.Wenn wir Spieler zwischen dem normalen und dem korrupten Zustand eines Raums teleportieren, können wir keine Spieler sitzen lassen, weil die CFrame nicht funktionieren würde, also hat der Sitzmanager eine Funktion, die Sitzung einige Sekunden vor und nach dem Teleportieren zu deaktivieren oder zu aktivieren.

Schubladenmanager

Das DrawerManager -Skript verwendet ein Drawer2 -Tag und CollectionService, um auf Schubladen zu klicken, um sie zu öffnen oder zu schließen, und entsprechendes Audiodateienabzuspielen.Die Öffnungs- und Schließaktion erfolgt durch Festlegen von TargetPosition für eine PrismaticConstraint .

Tötungsvolumen

In einigen Bereichen des Hauptspielbereichs, wie z. B. die elektrischen Funken und das Wasser in der Nähe des Beginns der Straße, die zum Haus führt, kann ein Spieler seine Humanoid.Health Einstellung auf 0 setzen, wenn er eine Lautstärke mit dem Tag KillVolume betritt.Das KillVolumes -Skript verwendet Touched:Connect, um zu bestimmen, wann ein Spieler eine Lautstärke betritt, und reduziert dann seine Gesundheit auf 0.

Spieler-Missionsrespawn

Das PlayerMissionRespawn -Skript verwendet ein RespawnVolume -Tag und CollectionService, um mit Volumen umzugehen, die Spieler respawnen lassen, wenn sie berührt werden.Wir haben diese Volumen unter korrupte Räume platziert, da viele Missionen Lücken oder bewegliche Plattformen haben, auf denen der Spieler herunterfallen könnte.Wenn berührt, spielt das Skript eine kleine Teleport_Jump -Szene und ruft GameStateFunc mit GameEvents.PlayerRespawn Befehl auf.

Wenn die Verarbeitung GameEvents.PlayerRespawn durchgeführt wird, kann das Skript RespawnPositions verwenden, wenn die Mission es bereitstellt.Wenn nicht, verwendet es TeleportPositions für die spezifische Mission.Wir haben kein "Kontrollpunkt"-System, also wählt CalcClosestTeleportPos einfach die nächsten Respawn oder Teleport -Orte aus, von denen der Spieler die RespawnVolume getroffen hat, mit der einzigen horizontalen, "2D"-Entfernung.

Kleine Hilfesysteme

Klaviermanager

Das PianoManager -Skript verwendet ein Piano -Tag und CollectionService, um ClickDetectors hinzuzufügen und einen der Klaviersounds zu spielen, wenn auf der Tastatur geklickt wird.

Ritualunterstützung

Das Foyer, in dem Spieler Seals platzieren, hat eine komplizierte Konstruktion, die Änderungen unterzieht, wenn jedes Siegel an seinem definierten Ort platziert wird.Zum Beispiel spielen bestimmte Ereignisse ab, abhängig von der Anzahl der platzierten Seelen, um Lichter und Strahlen zu aktivieren/deaktivieren, die Transparenz bestimmter Objekte zu ändern usw.Der Ritualunterstützung ModuleScript ist ein kleiner Wrapper über EventManager:Invoke Aufrufe für diese Ereignisse, der dem Ereignis Parameter wie z. B. welches "Wurzelobjekt" es spielen soll, abhängig davon, welche spezielle Versiegelung platziert wurde.

WiederherstellbareManager

Einige greifbare Objekte sind für das Gameplaywichtig, wie Seelöwen, und wir wollten nicht, dass sie verloren gehen, wenn ein Spieler sie irgendwo ablegte.Wenn ein Objekt ein Wiederherstellbare -Tag hat, erinnert sich das WiederherstellbareManager -Skript an seine Transformation, wenn es zum wiederherstellbaren System hinzugefügt wird.Wenn ein Spieler ein solches Objekt fallen lässt, ruft das Greifsystem restorableManager.StartTracking an.Wenn das Objekt in fünf Sekunden nicht wieder aufgehoben wird, positioniert das RestorableManger -Skript es an der ursprünglichen Transformation und setzt die Verfolgungszeit zurück.

Portale

In einigen Missionen teleportieren wir Spieler eine kurze Distanz innerhalb einer Mission, wie Spieler respawnen, die von einer drehenden Plattform fallen.Um die Einrichtung dieser Art von Teleportation zu vereinfachen, die wir "Portale" im Skript, das. PL: die Skriptsnennen, wird eine Hilfefunktion ProcessPortal in DemoUtils verwendet.Zum Beispiel, wenn P1 das Teil ist, das den initialen Auslöserdefiniert, und P2 das Teil ist, das die Zielspieler-Transformierung definiert, könnte der folgende Code-Snippet solche Portalfunktionalität definieren:


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

Prozessportal bearbeitet die Überprüfung, dass ein anderer Teil ein Mensch ist, teleportiert den Spieler durch eine CFrame Koordinätsänderung und ruft eine kleine Cutscene auf, um den Übergang mit einem Teleport_Jump Ereignis in EventManager zu verbergen.

Konfigurationsskripte

Wir haben mehrere Konfigurations-, Datendefinitions- und gemeinsame Funktionsskripte: DemoConfig . Definitionen von Missionen. Enumerationen für Spielzustände, Ereignisse für Client-Server-Kommunikation. DemoGlobalSettings .Wir entwickeln an einem Ort, veröffentlichen (und spielen) aber in anderen.Das Skript prüft placeID und aktiviert/deaktiviert verschiedene Cheats und Diagnosefunktionen. DemoUtils .Verschiedene Anwendungsfunktionen.Umgang mit Transformationen.Sichtbarkeit einstellen, verankert oder andere Eigenschaften.Überprüfen eines Punkts in einer Auswahlbox.Objekte in der Hierarchie mit dem "gestrichenen" Namen finden.Verwaltung von TempStorage (die verwendet werden kann, um Modelle vorübergehend "an einen weit entfernten Ort" zu verschieben und später zurückzubringen).Klicken Sie auf Erkennungshelfer.Schnappunterstützung.Unterstützung beim Überprüfen von Tags (insbesondere entlang der Hierarchie).Verbindung von Auslösern mit EventManager. AudioUtils . Ein paar Funktionen, um gewichtete zufällige Sounds aus einem festlegenzu spielen. GrabUtil . Hilfsfunktionen zum Greifen.