Unità ora stai pensando con i componenti

Mentre Unity è un'incredibile piattaforma di gioco, abituarsi ad esso richiederà un po 'di lavoro iniziale, poiché probabilmente dovrai spostare i tuoi ingranaggi cognitivi per afferrarne il basati su componenti architettura.

Mentre la classica programmazione orientata agli oggetti (OOP) può essere, ed è, utilizzata, il flusso di lavoro di Unity si basa fortemente sulla struttura dei componenti, che richiede il pensiero basato sui componenti. Se hai familiarità con i componenti, è fantastico; se no, non è un problema. Qui, ti darò un corso accelerato sui componenti di Unity.

Immagine in anteprima: Old Cogs di Emmanuel Huybrech.


Che cos'è un componente?

Prima di procedere su come lavorare e pensare con i componenti, assicuriamoci di comprendere appieno quali sono esattamente.

Nel mondo della programmazione, i concetti di componenti e disaccoppiamento vanno di pari passo. Un componente può essere pensato come un pezzo più piccolo di una macchina più grande. Ogni componente ha il proprio lavoro specifico e può generalmente (e in modo ottimale) svolgere il proprio compito o scopo senza l'aiuto di alcuna fonte esterna. Inoltre, i componenti raramente appartengono a una singola macchina e possono essere uniti a vari sistemi per svolgere il loro compito specifico, ma ottenere risultati diversi quando si tratta di un'immagine più grande. Questo perché i componenti non solo non si preoccupano di quell'immagine più grande, ma anche non so nemmeno che esiste.

Un classico esempio di componenti sono i pezzi di una macchina, ma è noioso, perché non sono troppo in auto. Invece, considera un controller Xbox 360. Tt ha due stick analogici, vari pulsanti, trigger e così via. Non solo l'intero controller è di per sé un componente, ma ogni singolo aspetto del controller è un componente.

Foto di Futurilla.

Il tasto X può: essere premuto; inviare le informazioni che è stato premuto; essere rilasciato; e invia informazioni che sono state rilasciate. Non ha idea ci sono vari altri pulsanti proprio accanto ad esso, né gli importa.

Il controller stesso è un componente, composto da altri componenti (tutti i pulsanti, joystick e trigger), perché può inviare dati a qualunque cosa sia collegato, ma non gli interessa quale sia quell'oggetto (Xbox, PC, alcuni Creazione di Arduino, o qualsiasi altra cosa). Né il pulsante X, né il controller stesso, devono sapere a quale gioco stai giocando, poiché continuerà a svolgere il proprio lavoro indipendentemente dal destinatario delle informazioni. 

La funzione del controller è una strada a senso unico e il suo compito non cambierà mai a causa di ciò a cui è collegato. Questo lo rende un componente di successo, sia perché può fare il suo lavoro come dispositivo standalone, ma anche perché può fare il suo lavoro con multiplo dispositivi.


Come e perché Unity favorisce i componenti?

Unity è stato costruito pensando ai componenti e mostra. Uno degli aspetti più preziosi e distintivi di Unity è che si tratta di un programma molto visivo. Ho lavorato allo sviluppo di giochi per anni e, a parte i miei primi ID Flash IDE, ho lavorato principalmente con fogli di sprite PNG e un editor di codice come FlashDevelop, che non è affatto visivo.

L'unità è l'esatto opposto. Unity ti consente di vedere tutto ciò su cui stai lavorando e in tempo reale. Ciò significa che puoi testare il tuo progetto, vedere il tuo progetto in esecuzione in una finestra separata, apportare modifiche al tuo codice o agli oggetti di gioco e vedere quelle modifiche riflesse dal vivo. La quantità di potenza che questo sistema offre a uno sviluppatore è immensa, ed è ora, a mio parere, un aspetto essenziale dello sviluppo moderno del gioco. Tutto ciò è reso possibile dall'architettura basata su componenti di Unity.

L'ispettore

Nel caso tu non abbia familiarità con Unity, ti spiegherò l'ispettore. Questo è un pannello in Unity che mostra tutte le proprietà di un oggetto di gioco. Se fai clic sul tuo giocatore nel mondo (in fase di esecuzione o prima) sarai in grado di vedere tutto su quell'oggetto.

Se il tuo avatar giocatore ha sei componenti su di essi, ognuno sarà elencato in una scheda separata, e ogni variabile pubblica sarà disponibile per te per vedere e modificare. Se il tuo avatar giocatore ha un inventario, non solo vedrai che ha un inventario, sarai anche in grado di vedere gli oggetti in quell'inventario e quale indice nella lista o matrice occupata da ciascun particolare oggetto. Se raccogli un nuovo oggetto durante il gioco mentre lo stai testando, lo vedrai aggiunto all'inventario, dal vivo. Puoi anche aggiungere o rimuovere elementi da quell'inventario, che ti consentirebbe di testare rapidamente nuovi elementi, che potresti addirittura creare mentre il gioco funziona.

L'ispettore dell'Unità.

Mentre il montaggio dal vivo è follemente potente, non dipende esattamente dall'uso dei componenti. È possibile modificare uno script e vedere quelle modifiche riflesse dal vivo, ma ciò è limitante rispetto a ciò che i componenti consentono di fare.

Prendi in considerazione uno sparatutto spaziale verticale. Quando metti alla prova il tuo progetto nella maggior parte degli altri ambienti, vedrai come gioca il tuo gioco, prendi appunti, poi rientra nel codice e modifichi le cose, solo per compilare di nuovo il progetto e testare quei punti. Se hai una configurazione dal vivo, puoi modificare quel codice al volo e vedere quelle modifiche mentre giochi, il che è ancora meglio. Detto questo, se non si usano componenti, si dovrà cambiare molto codice per vedere gli effetti principali, il che richiede tempo, e questo piuttosto vanifica lo scopo dell'editing live.

Se si sta lavorando con componenti, è possibile aggiungere nuovi componenti in due secondi. Puoi scambiare i cannoni della tua nave con le pistole usate da un boss (supponendo che tu abbia programmato i tuoi componenti per funzionare da soli, come dovrebbero fare i componenti buoni), puoi cambiare il tuo sistema di salute a cinque colpi con quello scudo di ricarica di Halo come te programmato per un altro gioco. puoi aggiungere una serie di incantesimi a uno dei tuoi personaggi e tutto in pochi secondi.

Non è necessario modificare alcun codice, non è necessario ricompilare, semplicemente trascinare e rilasciare o selezionare il componente desiderato da un elenco a discesa e aggiunto. Questo tipo di potenza è inestimabile per il bilanciamento del gioco e consente di risparmiare moltissimo tempo.


Passare al pensiero basato sui componenti

La parte più difficile del lavoro con i componenti è imparare come strutturare i progetti quando li si utilizza. Per la maggior parte dei programmatori, questo probabilmente significa che creerai molti più script, ognuno dei quali eseguirà attività più piccole e più specifiche.

Anche il modo in cui comunichi tra gli script è un ostacolo decente, poiché avrai molti più pezzi e meno classi giganti in cui ogni oggetto conosce ogni altro oggetto. Ci sono ovviamente dei modi per aggirare questo, come le variabili statiche per i componenti principali del gioco (giocatori, punteggio e così via), ma che raramente funziona per tutto (e non è consigliato), e ci sono metodi avanzati per strutturare correttamente i componenti e rimanere disaccoppiati.

Fortunatamente, dal momento che Unity è stato costruito pensando ai componenti, ha un numero di funzioni integrate che ci aiutano a raggiungere questo obiettivo. Ci sono funzioni per ottenere riferimenti a un componente specifico, per controllare tutti gli oggetti per vedere quali contengono un componente specifico, ecc. Con queste varie funzioni, puoi facilmente recuperare le informazioni necessarie per creare quella strada a senso unico e magica dove i componenti possono comunicare con gli oggetti che influenzano, ma il componente stesso non ha idea di cosa sia esattamente quell'oggetto. Combina questo con l'uso di interfacce e hai abbastanza potenza di programmazione per affrontare qualsiasi approccio, semplice o complesso.

Esempio: tipi di nemici

In un sistema di ereditarietà OOP, potresti avere una base Nemico classe che conteneva tutte le funzioni che la maggior parte dei tuoi nemici avrebbe usato, e quindi potresti estenderle per aggiungere funzionalità specifiche.

Se hai mai effettivamente implementato un tale sistema, sei consapevole che tra la tua base Nemico classe, e forse la tua base GameObject (o equivalente) classe, si finisce con un sacco di ingombro non necessario di avere variabili e funzioni che alcune classi hanno bisogno, ma molti non lo fanno. interfacce può aiutare con questo, ma non sono sempre la soluzione.

Ora, diamo un'occhiata allo stesso setup, ma pensiamo con i componenti. Hai ancora vari nemici, che condividono molte funzionalità comuni, ma ognuno di essi ha caratteristiche uniche.

Il primo passo è quello di rompere tutte le funzionalità in pezzi. Si potrebbe pensare avere salute e sta morendo fanno parte dello stesso sistema, ma anche quell'esempio può essere suddiviso in un componente del sistema sanitario e un componente del sistema di morte. Questo perché la tua salute è la tua salute, e niente di più. Quando raggiunge lo zero, non spetta al sistema sanitario decidere cosa succederà dopo, è solo fino al sistema sanitario sapere che è, di fatto, a zero. Altri sistemi, come un sistema di morte, possono leggere queste informazioni e quindi scegliere di fare ciò che vogliono.

Forse il sistema di morte genererà un nuovo nemico (pensa a un grande nemico che si spezza in pezzi); forse lascerà un power-up; forse aggiungerà un effetto di esplosione allo schermo. Indipendentemente da ciò che accade, il sistema sanitario non fa parte di questo, ed è così che facciamo componenti puliti e utili.

Quando pensiamo al movimento, potremmo pensare che tutto il movimento debba essere in un singolo copione. Ma alcuni nemici in alcuni giochi non possono camminare; possono solo saltare. Alcuni nemici possono camminare, ma non possono saltare. Pensare a queste cose è come individuare dove i componenti potrebbero e dovrebbero esistere. Quando si tratta di mobilità, potremmo separare il salto da camminare o correre, separare il volo, e così via, così da darci un codice più pulito e una maggiore versatilità.

I componenti rendono il nostro codice più ordinato (senza inutili variabili e funzioni), ma rendono anche il processo di creazione dei nemici molto più flessibile e piacevole. Con ogni singolo elemento della funzionalità del nemico impostato come componente, possiamo trascinare e rilasciare aspetti dei nemici e vedere come si comportano, e anche in tempo reale, se usiamo Unity.

Supponiamo che tutte le seguenti caratteristiche siano già programmate. Durante il nostro processo di creazione del nemico, potremmo creare tre nemici vuoti, che sono tutti solo prefabbricati vuoti in Unity. Possiamo quindi trascinare su un sistema sanitario, un sistema di rilascio degli oggetti e un sistema di morte, poiché sappiamo che tutti i nostri nemici, indipendentemente dalle differenze, avranno salute, morire e far cadere un oggetto. Possiamo effettivamente selezionare tutti e tre i prefabbricati contemporaneamente, quindi trascinare questi componenti nel pannello Inspector e aggiornarli tutti e tre contemporaneamente.

Successivamente, sappiamo che un nemico sarà in grado di volare, quindi selezioniamo quell'unico nemico e trasciniamo a volante componente su di esso. Un altro può individuare un bersaglio nel gioco, e spararci sopra, così ci lanciamo su a fuoco al bersaglio script di componenti. Il terzo può lanciare una barriera che blocca tutti gli attacchi per un breve periodo, quindi lanciamo il barriera componente.

Ora abbiamo tre nemici unici, che condividono tutti alcuni componenti, ma tutti hanno anche componenti che si applicano solo a loro. La parte divertente è che rendere questi nemici è semplice, e sperimentare nuove varianti è facile come trascinarle e rilasciarle. Vuoi un nemico volante, con una barriera, che possa bersagliare un nemico e sparargli contro? Trascina tutti i componenti di cui sopra su un singolo nemico, e hai proprio questo!


Conclusione

Pensare con i componenti potrebbe non essere facile, ma sicuramente ha i suoi benefici. Continuerai a utilizzare entrambi i componenti e l'ereditarietà nella tua programmazione futura, ma è estremamente utile espandere la tua pletora di modi per affrontare lo stesso problema vedendo varie prospettive.

Quando si tratta di Unity, puoi usare qualsiasi metodo tu preferisca, ma i componenti sono decisamente favoriti, e non ha senso combattere contro un flusso di lavoro così straordinario. Imparare l'unità e cambiare il mio modo di pensare per lavorare con i componenti è stato un ostacolo moderatamente difficile da superare, ma ora che sono qui, non mi vedo tornare presto.