Sistemi di supporto

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

Abbiamo utilizzato i seguenti sistemi per supportare sia i sistemi di gioco di base, sia qualsiasi obiettivo dei requisiti di progettazione principali.

UseManager

UseManager ha fornito una semplice API per applicare un oggetto catturato su qualcosa, come un pezzo di abbigliamento a strati su un manichino.La funzione principale per questa API è UseManager.AddUse (etichette, oggetti target, distanza, onSuccess, onNothingEquipped, onWrongEquipped, dati extra), che lega un insieme di etichette a targetObjects .Quando un giocatore ha un oggetto con uno dei tag e clicca su un targetObject, viene chiamata la funzione di richiamo onSuccess.Altre funzioni di chiamata ci hanno permesso di mostrare agli utenti informazioni visive extra se viene eseguito un clic senza oggetto catturato o con il tipo di Articolosbagliato.

Potremmo rimuovere l'"uso" con UseManager.RemoveUse, che era di solito utile quando una missione era finita o un oggetto specifico era "usato".Inoltre, potremmo aggiungere o rimuovere bersagli con AddUseTargets e RemoveUseTargets .

Evidenze

Quando un giocatore era vicino a un oggetto di interesse, come una foca, volevamo che quell'oggetto si distinguesse dai suoi dintorni.Per implementarlo, abbiamo creato un LocalScript chiamato HighlightItems che utilizza una sfera centrata attorno al giocatore per rilevare tocchi con altre maglie, connessa a Touched e TouchEnded eventi.La funzione getHighlight controlla diversi tag su una mesh toccata o sui suoi genitori utilizzando una funzione ausiliaria GetTaggedObjectUpHierarchy .Se nessun highlight non è necessario, potremmo rimuoverlo forzatamente usando un tag NoHighlight .Tuttavia, se è necessario ma non si adatta a diverse altre etichette, potremmo forzarlo usando il tag Importante .

Questa LocalScript utilizza una nuova funzione del motore Highlight che traccia un contorno di un oggetto e/o riempie l'interno dell'oggetto con un colore definito; per ulteriori informazioni su come utilizzare questa Proprietà, vedi Evidenziazione degli oggetti . Highlights e il cursore del mouse OnItemIndicator sistemi lavorano insieme, quindi Highlights non solo determinano se una mesh ha bisogno di un evidenziazione, ma forniscono anche un tipo di mesh per OnItemIndicator .

HighlightItemsFunc viene utilizzato per comunicare con altri sistemi client.Ad esempio, EventManager lo utilizza con un comando Abilita per abilitare o disabilitare un Highlight in alcune scene, e OnItemIndicator lo utilizza con GetType per chiedere il tipo di oggetto che è.Per rilevare quando un oggetto non è più presente, come quando una stanza corrotta viene distrutta, ci connettiamo a CollectionService.GetInstanceRemovedSignal .

Lore e ThoughtBubbles

Lore e Bubble di pensiero sono 2 sistemi simili.Lore utilizza un ScreenGui come contenitore di interfaccia utente sullo schermo con un figlio Frame per controllare la ridimensionamento e la ridimensionamento dei suoi figli TextLabels e ImageLabels , e Lore attende che il giocatore faccia clic ovunque sullo schermo per rimuoverlo.Allo stesso modo, le bolle di pensiero utilizzano un BillboardGui con un figlio TextLabel per gli oggetti non appresi, e visualizza il dialogo nello spazio 3D vicino all'oggetto per un periodo di tempo specificato e un periodo di ricarica senza che il testo occupi l'intera schermata.Per maggiori informazioni sul design dietro questi sistemi, vedi Lore e Bubble di pensiero.

Lore è implementato nel LoreManger LocalScript .Quando viene cliccato o toccato, lancia un raycast utilizzando una funzione ausiliaria utils.RaycastAlongPointingDir e utilizza un Gruppo NoPlayerCollision .Se una mesh sotto il clic o uno dei genitori ha un tag Lore o Bolla di pensiero , visualizziamo l'interfaccia utente.Il testo, la didascalia e l'immagine sono definiti dagli attributi LoreText, LoreCaption e LoreImage sull'oggetto.

Nota che utilizziamo Camera.ViewportPointToRay o Camera.ScreenPointToRay per costruire il raggio, a seconda se è stato chiamato da un non tocco o da un tocco.Le coordinate sono in sistemi di coordinate leggermente diversi.Per il Topo, or mouse as computer mouse, li otteniamo da Class.UserInputService.InputEnded``:Connect per il MouseButton1, e per i dispositivi touch, li otteniamo da Class.UserInputService.TouchTapInWorld``:Connect .

Le Bubble di pensiero sono simili in generale, utilizzando un raycast per controllare se una mesh o i suoi genitori hanno un tag Bubble di pensiero .Utilizza anche l'attributo ThoughtText per il testo e un tag Bolla di pensiero per indicare un oggetto placeholder utilizzato per posizionare l'interfaccia utente nel Mondo.Le bolle di pensiero che utilizzano lo stesso oggetto posizionale ma hanno testi diversi hanno tempi di ricarica diversi.

Casi speciali

Lore ha un paio di casi speciali, uno dei quali sono le foche corrotte.Quando un giocatore fa clic su un sigillo corrotto, visualizza l'interfaccia utente della lore e attende un clic per avviare una missione, che influisce sul flusso di gioco.Questo è gestito dal GameStateClient che utilizza un bindable LoreManagerFunc per richiedere l'interfaccia utente lore.Un callback viene fornito al sistema Lore da GameStateClient per sapere quando la lore è "chiusa" dal Giocatore.Un altro caso speciale è quando Bubble di pensiero e Lore etichette sono sullo stesso oggetto.In questo caso, per evitare un sovrapposizione di testo di bolla di pensiero e conoscenza, eseguiamo la bolla di pensiero dopo che la conoscenza è chiusa. LoreManager gestisce anche un caso speciale mostrando una piccola cutscene quando si fa clic su porte disabilitate che sono bloccate fino a quando il giocatore non raccoglie il sigillo della stanza.

Indicatore di elemento OnItem

Vogliamo mostrare icone diverse nel centro dello schermo quando il giocatore sta guardando determinati oggetti di interesse.Lo script cliente OnItemindicator esegue un raycast lungo la fotocamera Class.CFrame.LookVector e analizza i risultati.In base ai risultati, imposta un'immagine nell'OnItemIndicator2 ScreenGui .

Quando non vengono colpiti elementi di interesse, l'icona predefinita è un piccolo punto.Potremmo impostare qualsiasi icona aggiungendo un attributo OnItemIndicator a una Mesh, magliaspecifica, utilizzando i nomi da onItemIndicatorImages , come Hand, Eye o DoorCurrentlyLocked.L'attributo è necessario solo in rari casi e la maggior parte del tempo altri tag o sistemi esistenti forniscono il tipo di Icona.Per maggiori dettagli, vedi la funzione Update .

I controlli di tipo eseguono alcuni in un ordine di priorità.Dopo l'SoprascrivereOnItemIndicator , controlliamo se è afferrabile o un cassett per l'icona "mano" attraverso utils.CanGrabModel(model) o utils.GetTaggedObjectUpHierarchy("Drawer2", model) .Dopo ciò, chiamiamo HighlightManager che determina lo Statodi evidenziazione, i tipi di oggetti e l'icona da utilizzare.Ad esempio:


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

Le etichette Lore e ThoughtBubble vengono controllate in seguito controllando le etichette.Per le porte, abbiamo 2 icone diverse: DoorCurrentlyClosed e DoorAlwaysLocked . DoorManager > imposta un attributo true o false DoorEnabled per le porte che possono essere aperte o chiuse, e utilizziamo la presenza e il valore dell'attributo.Gli oggetti che sembrano porte ma non si aprono hanno il tag DoorLocked .

Gestore delle porte

Il DoorManager utilizza un tag Door e per gestire l'apertura e la chiusura delle porte.La porta ha trigger anteriori e posteriori che connettiamo con il tocco e gli eventi touchEnded .Abbiamo creato gli adolescenti per aprire e chiudere una porta dai lati frontale e posteriore.Manteniamo una mappa giocatoriNear (di giocatori che toccano i trigger, separatamente per il lato anteriore e posteriore.

Ogni porta ha un semplice sistema di stato, DoorState (Chiuso, Apertura, Aperto, Chiusura), con adolescenti utilizzati per le transizioni.Potremmo abilitare o disabilitare la capacità di una porta di aprire o chiudere da sistemi esterni chiamando DoorManager.EnableDoor, che imposta un attributo DoorEnabled.

Animatore principale

Il MasterAnimator LocalScript riproduce immagini animate (atlante di texture), che usavamo per animare gli schermi TV.Per scorrere le immagini, avevamo bisogno di conoscere un insieme di parametri: numero di righe e colonne, totale di frame, perios, dimensioni delle immagini e un insieme di ID delle immagini.Il sistema ci ha permesso di animare attraverso più immagini, ognuna delle quali potrebbe essere divisa in righe e colonne di sottounimmagini.Potremmo fornire questi dati attraverso attributi o valori, ma in questa esperienza, abbiamo utilizzato gli script ausiliari.UpdateImageAnimations(dT) calcola quale immagine o sottimmagine abbiamo bisogno di mostrare utilizzando il tempo e i parametri.Se abbiamo bisogno di cambiare a una nuova immagine, impostiamo Image.Se dobbiamo cambiare qualsiasi sottimmagine, impostiamo ImageRectOffset .

Un oggetto con un'animazione SurfaceGui avrebbe un Animatore ModuleScript, con lo scopo principale di fornire una funzione Animator.GetParams che restituisce tutti i parametri.Questo aiuta il MasterAnimator LocalScript che utilizza il tag Animazione dell'immagine e CollectionService per raccogliere tali oggetti e trovare l'Animatore ModuleScript sotto di essi.Quindi usa pcall per richiedere Animator ModuleScript e chiamare GetParams su di esso.

Animazioni locali dello spazio

Le Animazioni di spazio locale LocalScript utilizza un tag LocalSpaceRotation per ruotare principalmente oggetti "cosmetici" con una velocità di rotazione e un ritardo dato intorno all'asse X, Y o Z.Abbiamo usato questo per oggetti distanti con cui i giocatori non interagirebbero, o per oggetti più piccoli che non influiscono molto sulla simulazione.Parametri definiti attraverso il Speed , Delay e Axis valori.Per i dettagli di implementazione, vedi Reti di cloud rotanti.

Gestore della lampada frontale

Il HeadlampManager gestisce quando gli utenti selezionano l'on-screen per attivare o disattivare il riflettore sulla loro testa, lancia commenti al server utilizzando HeadlampEvent e tira su e giù i suoni di attivazione e disattivazione.Quando viene aggiunto un personaggio, o il loro Head è cambiato, la funzione giveCharacterHeadlamp clona la lampada templateHeadlamp e posiziona la lampada utilizzando alcuni spostamenti e rotazioni dal FaceFrontAttachment .

Gestore del sedile

Non vogliamo che i giocatori si siedano automaticamente quando sono vicini a un oggetto su cui possono sedersi.Invece, vogliamo richiedere agli utenti di fare clic vicino a un sedile per sedersi.Lo script SeatManager aggiunge ClickDetectors in base a un tag Sedile , e chiama seat:Sit(humanoid) quando viene cliccato.Durante il teletrasporto dei giocatori tra lo stato normale e corrotto di una stanza, non possiamo avere giocatori seduti perché CFrame la modifica delle coordinate non sarebbe in grado di funzionare, quindi il SeatManager ha una funzionalità per disabilitare o abilitare il sedere qualche secondo prima e dopo il Teletrasporto.

Gestore Cassetti

Lo script DrawerManager utilizza un tag Drawer2 e CollectionService per gestire il clic sui cassetti per aprirli o chiuderli e riprodurre qualsiasi audio/suonocorrispondente.L'azione di apertura e chiusura viene eseguita impostando TargetPosition per un PrismaticConstraint .

Volume di uccisione

In un paio di aree della zona principale di gioco, come le scintille elettriche e l'acqua vicino all'inizio della strada che conduce alla casa, un giocatore può impostare il proprio Humanoid.Health a 0 quando entra in un volume con il tag KillVolume .Lo script KillVolumes utilizza Touched:Connect per determinare quando un giocatore entra in un volume, quindi riduce la sua salute a 0 .

Rigenerazione della missione del giocatore

Lo script PlayerMissionRespawn utilizza un tag RespawnVolume e CollectionService per gestire i volumi che fanno respawnare i giocatori quando vengono toccati.Abbiamo posizionato questi volumi sotto stanze corrotte, poiché molte missioni hanno spazi vuoti o piattaforme in movimento in cui il giocatore potrebbe cadere.Quando viene toccato, lo script riproduce una piccola scena Teleport_Jump e invoca GameStateFunc con il comando GameEvents.PlayerRespawn.

Durante il trattamento di GameEvents.PlayerRespawn, lo script può utilizzare RespawnPositions, se la configurazione della missione lo fornisce.Altrimenti, utilizza TeleportPositions per la missione specifica.Non abbiamo un sistema di "checkpoint", quindi CalcClosestTeleportPos seleziona solo i punti più vicini Respawn o Teleport da dove il giocatore ha colpito il RespawnVolume, utilizzando l'unica distanza orizzontale, "2D".

Piccoli sistemi ausiliari

PianoManager

Lo script PianoManager utilizza un tag Piano e CollectionService per aggiungere ClickDetectors e riprodurre uno dei suoni del pianoforte quando viene cliccato sulla tastiera.

Supporto rituale

Il foyer in cui i giocatori piazzano le sigillature ha una complicata contrapposizione che subisce cambiamenti ogni volta che una sigillatura viene posizionata nella sua posizione definita.Ad esempio, a seconda del numero di sigilli posizionati, eventi specifici giocano per abilitare/disabilitare luci e raggi, cambiare la trasparenza di determinati oggetti, ecc.Il RitualSupport è un piccolo wrapper su chiamate per quegli eventi, fornendo parametri all'evento, come quello "root oggetto" su cui giocare, a seconda di quale sigillo specifico è stato posizionato.

RestorableManager

Alcuni oggetti afferrabili sono importanti per il Partita, come le foche, e non volevamo che si perdessero se un giocatore li lasciasse da qualche parte.Se un oggetto ha un tag Ripristinabile , lo script RipristinabileManager ricorda la sua trasformazione quando viene aggiunto al sistema di ripristino.Quando un giocatore fa cadere un oggetto del genere, il sistema di presa chiama restorableManager.StartTracking .Se l'oggetto non viene ripreso in cinque secondi, lo script RestorableManger lo posiziona nella trasformazione originale e ripristina il tempo di tracciamento.

Portali

In alcune missioni, teletrasportiamo i giocatori a una breve distanza all'interno di una missione, come respawnare i giocatori che cadono da una Piattaformarotante.Per semplificare la creazione di questo tipo di teletrasporto, che chiamiamo "Portali" in script, viene utilizzata una funzione ausiliaria ProcessPortal in DemoUtils .Ad esempio, se P1 è la parte che definisce il grillettoiniziale e P2 è la parte che definisce la trasformazione del giocatore di destinazione, il seguente snippet di codice potrebbe definire tale funzionalità del portale:


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

ProcessPortal gestisce il controllo che l'altra parte è un uomo, teletrasportando il giocatore attraverso un cambio di coordinate CFrame e invocando una piccola cutscene per nascondere la transizione utilizzando un evento Teleport_Jump in EventManager.

Script di configurazione

Abbiamo diversi script di configurazione, definizione dei dati e funzionalità comuni: DemoConfig . Definizioni di missioni.Enumerazioni per stati di gioco, eventi per comunicazioni client-server. DemoGlobalSettings .Sviluppiamo in un Posto, ma rilasciamo (e Test di giocabilità) in altri.Lo script controlla placeID e abilita/disabilita varie funzionalità di trucchi e debugging. DemoUtils .Varie funzioni utilitarie.Affrontare le trasformazioni.Impostazione della visibilità, ancorata o di altre proprietà.Controllo di un punto in una Quadro di selezione.Trovare oggetti nella gerarchia per nome "dotato".Gestire TempStorage (che può essere utilizzato per spostare temporaneamente i modelli "da qualche parte lontano" e riportarli più tardi).Fai clic su aiutanti del rilevatore.Prendere il Assistenza.Supporto per il controllo delle etichette (specialmente lungo la gerarchia).Connessione di trigger a EventManager. AudioUtils . Un paio di funzioni per riprodurre suoni casuali pesati da un Impostare. GrabUtil . Funzioni ausiliarie per la presa.