La guida definitiva per principianti allo sviluppo di giochi in Unity

Unity è un ottimo strumento per la prototipazione di tutto, dai giochi alle visualizzazioni interattive. In questo articolo, esaminiamo tutto ciò che devi sapere per iniziare a utilizzare Unity.

Innanzitutto, un po 'di me: sono uno sviluppatore di unità per hobby, un modellatore 3d e un designer grafico che ha lavorato con Unity e Blender per oltre 5 anni. Ora sono uno studente di matematica finanziaria all'University College di Dublino e occasionalmente mi occupo di progettazione grafica, prototipazione web e prototipazione di giochi.

introduzione

Questo articolo è rivolto a chiunque non abbia mai utilizzato Unity prima d'ora, ma abbia qualche precedente esperienza di programmazione o di web design / sviluppo. Entro la fine di questo articolo, dovresti avere una buona panoramica generale del motore, nonché tutte le funzioni e il codice necessari per iniziare a creare un gioco di base.

Perché Unity?

Se vuoi creare giochi

Ci sono davvero pochissime opzioni quando si tratta di sviluppo di giochi indie. Le tre scelte principali se vuoi creare giochi sono Unreal, Unity o GameMaker.

Unity è probabilmente la meno ostinata delle 3 piattaforme. Ti offre un prodotto molto grezzo pronto all'uso, ma è altamente flessibile, ben documentato e altamente estensibile per costruire praticamente qualsiasi genere di gioco a cui puoi pensare.

Ci sono molti giochi di grande successo come Escape from Tarkov (FPS), Monument Valley (Puzzler) e This War of Mine (Strategia / Sopravvivenza), tutti costruiti in Unity.

In realtà il motore su cui crei il tuo primo gioco probabilmente non è critico, quindi il mio consiglio è solo di sceglierne uno e seguirlo.

Se vuoi prototipare le esperienze degli utenti

Poiché l'unità è solo un motore con un sacco di fisica, animazione e rendering 3D in tempo reale, è anche un ottimo spazio per realizzare prototipi interattivi a tutti gli effetti per studi UX.

Unity ha il pieno supporto per VR e AR e quindi potrebbe essere un ottimo strumento per esplorare architettura, automazioni e simulazioni con i clienti.

Sezioni di questo articolo

  • Perché Unity?
  • Finestra dell'editor di Unity
  • Oggetti di gioco Unity
  • Componenti incorporati Unity
  • Creazione di componenti personalizzati
  • Struttura di un MonoBehaviour
  • Manipolazione di oggetti di gioco
  • Raycasting
  • Rilevamento delle collisioni
  • Funzionalità avanzate
  • Consigli per i nuovi arrivati
  • Belle risorse e comunità
  • Conclusione

Finestra dell'editor di Unity

La finestra dell'editor è suddivisa in un paio di sezioni. Tratteremo questo molto brevemente poiché lo faremo costantemente riferimento in tutto l'articolo. Se hai già familiarità con questo, salta oltre!

Vista scena: consente il posizionamento e il movimento di GameObject nella scena. Vista gioco: mostra in anteprima come il giocatore vedrà la scena dall'ispettore della telecamera : fornisce dettagli sul GameObject selezionato nella scena. Risorse / Progetto: tutti i prefabbricati, le trame, i modelli, gli script ecc. Sono archiviati qui Gerarchia: consente l'annidamento e la strutturazione di GameObject all'interno della scena

Adesso siamo a posto!

Oggetti di gioco Unity

Cosa sono i GameObject

Gli oggetti GameObject sono l'elemento fondamentale di tutto il motore di gioco di Unity. Il nome quasi lo tradisce:

Tutto ciò che collochi in una scena in Unity deve essere racchiuso in un "oggetto di gioco".

Se hai un background di web design, puoi pensare a GameObjects come a degli elementi molto simili! Contenitori estremamente noiosi, ma altamente estensibili per creare funzionalità o immagini complesse.

Letteralmente tutto, dagli effetti particellari, alle telecamere, ai giocatori, agli elementi dell'interfaccia utente, ... (l'elenco continua) è un GameObject.

Creazione della gerarchia

Come uno sviluppo web, anche un GameObject è un contenitore. Proprio come annidate i messaggi per creare layout o astrazioni vari e desiderabili, potreste voler fare lo stesso con gli oggetti dei giochi.

La logica alla base della nidificazione degli oggetti di gioco è più o meno la stessa dello sviluppo web, fornirò alcuni esempi ...

Disordine ed efficienza

Web Analogy: hai molti elementi simili che possono essere generati dinamicamente al volo in risposta all'interazione dell'utente e vuoi tenerli in ordine. Traduzione Unity: stai costruendo un clone di Minecraft e hai un sacco di blocchi nella scena, devi aggiungere e rimuovere "blocchi" di blocchi dalla scena per motivi di prestazioni. Quindi averli associati a un GameObject vuoto per ogni blocco ha senso, poiché l'eliminazione del blocco genitore rimuove tutti i blocchi figli.

Posizionamento

Analogia Web: vuoi mantenere la posizione del contenuto contenuto "rispetto" al contenitore e non alla pagina web. Traduzione Unity: hai creato un gruppo di droni helper che si muovono intorno al giocatore. In realtà non preferiresti scrivere codice per dire loro di inseguire il giocatore, quindi li installi come figli dell'oggetto di gioco del giocatore.

Componenti incorporati Unity

Il modello dei componenti dell'attore

I GameObject da soli sono piuttosto inutili, come abbiamo visto sono praticamente solo contenitori. Per aggiungere funzionalità a loro dobbiamo aggiungere componenti, che sono essenzialmente script scritti in C # o Javascript.

Unity funziona su un modello Actor Component, in poche parole i GameObjects sono gli attori ei Components sono i tuoi script.

Se hai già scritto app Web in precedenza, avrai familiarità con l'idea di creare piccoli componenti riutilizzabili come pulsanti, elementi del modulo, layout flessibili che hanno varie direttive diverse e proprietà personalizzabili. Quindi assemblare questi piccoli componenti in pagine web più grandi.

Il grande vantaggio di questo approccio è il livello di riutilizzabilità e canali di comunicazione chiaramente definiti tra gli elementi. Allo stesso modo, nello sviluppo del gioco, vogliamo ridurre al minimo il rischio di effetti collaterali indesiderati. Piccoli bug tendono a perdere il controllo se non stai attento e sono estremamente difficili da eseguire il debug. Pertanto la creazione di componenti piccoli, robusti e riutilizzabili è fondamentale.

Componenti chiave incorporati

Penso che sia giunto il momento per alcuni esempi dei componenti integrati forniti dal motore di Unity Games.

  • MeshFilter: consente di assegnare materiali a una mesh 3D a un GameObject
  • MeshRender: consente di assegnare materiali a una mesh 3D
  • [Box | Mesh] Collider: Abilita il rilevamento di GameObject durante le collisioni
  • Rigidbody: consente la simulazione fisica realistica per agire su GameObjects con mesh 3D e attiverà eventi di rilevamento sui box collider
  • Luce: illumina parti della scena
  • Videocamera: definisce la visualizzazione del giocatore da allegare a un GameObject
  • Vari componenti della tela dell'interfaccia utente per la visualizzazione delle GUI

Ce ne sono molti di più, ma questi sono i principali con cui dovrai familiarizzare. Un suggerimento è che puoi accedere a tutti i documenti per questi tramite il manuale di unità e il riferimento allo scripting offline ovunque ti trovi:

Creazione di componenti personalizzati

I componenti incorporati controllano principalmente la fisica e la grafica, ma per realizzare davvero un gioco, dovrai accettare l'input dell'utente e manipolare quei componenti standard così come gli stessi GameObject.

Per iniziare a creare componenti, vai nel GameObject desiderato> Aggiungi componente> digita il nome del tuo nuovo componente nella barra di ricerca> nuovo script (c #).

Come raccomandazione generale, sconsiglierei di utilizzare Javascript in Unity. Non è stato aggiornato con tutte le fantastiche cose fornite con ES6, e la maggior parte delle cose più avanzate si basa su cose C # portate su Javascript ... Diventa solo una gigantesca soluzione nella mia esperienza.

Struttura di un MonoBehaviour

Funzioni chiave

Tutti i componenti ereditano dalla classe MonoBehaviour. Include diversi metodi standard, soprattutto:

  • void Start () che viene chiamato ogni volta che un oggetto contenente lo script viene istanziato nella scena. Questo è utile ogni volta che vogliamo eseguire un codice di inizializzazione, ad es. imposta l'equipaggiamento di un giocatore dopo che si genera in una partita.
  • void Update () che viene chiamato ogni frame. Qui è dove andrà la maggior parte del codice che coinvolge l'input dell'utente, aggiornando varie proprietà come il movimento del giocatore nella scena.

Variabili dell'ispettore

Spesso vogliamo rendere i componenti il ​​più flessibili possibile. Ad esempio, tutte le armi potrebbero avere danni, velocità di fuoco, has_sight ecc. Diversi. Sebbene tutte le armi siano essenzialmente la stessa cosa, potremmo voler creare rapidamente diverse varianti tramite l'editor di unità.

Un altro esempio in cui potremmo voler fare questo è quando creiamo un componente dell'interfaccia utente che tiene traccia dei movimenti del mouse dell'utente e posiziona un cursore nella visualizzazione. Qui potremmo voler controllare la sensibilità del cursore ai movimenti (se l'utente stava usando un joystick o un gamepad invece di un mouse del computer). Quindi avrebbe senso avere queste variabili facilmente modificabili sia in modalità di modifica che sperimentandole durante il runtime.

Possiamo farlo facilmente semplicemente dichiarandole come variabili pubbliche nel corpo del componente.

Accettazione dell'input dell'utente

Ovviamente, vogliamo che il nostro gioco risponda all'input dell'utente. I modi più comuni per farlo sono l'utilizzo dei seguenti metodi nella funzione Update () di un componente (o in qualsiasi altro luogo che desideri):

  • Input.GetKey (KeyCode.W) Restituisce True Il tasto W è tenuto premuto
  • Input.GetKeyDown (KeyCode.W) Restituisce True alla prima pressione del tasto W.
  • Input.GetAxis ("Vertical"), Input.GetAxis ("Horizontal") Restituisce tra -1,1 movimento di input del mouse

Manipolazione di oggetti di gioco

Una volta che abbiamo l'input dell'utente, vogliamo che GameObjects all'interno della nostra scena risponda. Esistono diversi tipi di risposte che possiamo prendere in considerazione:

  • Traslazione, rotazione, scala
  • Crea nuovi GameObjects
  • Invio di messaggi a GameObject / componenti esistenti

Trasformazioni

I GameObject hanno tutti una proprietà di trasformazione che consente di eseguire varie utili manipolazioni sull'oggetto di gioco corrente.

I metodi sopra sono abbastanza autoesplicativi, basta notare che usiamo gameObject in minuscolo per fare riferimento al GameObject che possiede questa specifica istanza del componente.

In generale è una buona pratica usare [Position, Rotation] locale piuttosto che la posizione / rotazione globale di un oggetto. Questo di solito rende più facile spostare gli oggetti in un modo che abbia senso, poiché l'asse dello spazio locale sarà orientato e centrato sull'oggetto genitore piuttosto che sull'origine del mondo e sulle direzioni x, y, z.

Se è necessario convertire tra lo spazio locale e quello mondiale (come spesso accade), è possibile utilizzare quanto segue:

Come puoi immaginare, c'è un'algebra lineare abbastanza semplice dietro a questo accennato dall''inverso 'nel nome del metodo.

Creazione di nuovi GameObject

Poiché i GameObject sono praticamente tutto nella tua scena, potresti voler essere in grado di generarli al volo. Ad esempio, se il tuo giocatore ha una sorta di lanciatore di proiettili potresti voler essere in grado di creare proiettili al volo che hanno la loro logica incapsulata per il volo, infliggere danni, ecc ...

Per prima cosa dobbiamo introdurre la nozione di prefabbricato . Possiamo crearli semplicemente trascinando qualsiasi GameObject nella gerarchia della scena nella cartella delle risorse.

Questo essenzialmente memorizza un modello dell'oggetto che abbiamo appena avuto nella nostra scena con tutte le stesse configurazioni.

Una volta che abbiamo questi componenti prefabbricati, possiamo assegnarli alle variabili dell'ispettore (come abbiamo detto prima) su qualsiasi componente nella scena, in modo da poter creare nuovi GameObject come specificato dal prefabbricato in qualsiasi momento.

Possiamo quindi eseguire la "creazione di istanze" del prefabbricato e manipolarlo nella posizione desiderata nella scena e stabilire le relazioni genitore necessarie.

Accesso ad altri GameObject e componenti

Spesso abbiamo bisogno di comunicare con altri GameObject e con i loro componenti associati. Una volta che hai un riferimento a un oggetto di gioco, questo è piuttosto semplice.

ComponentName comp = some_game_object.GetComponent ();

Dopodiché puoi accedere a uno qualsiasi dei metodi / variabili pubblici del componente per manipolare il GameObject. Questa è la parte semplice, tuttavia ottenere effettivamente il riferimento a GameObject può essere fatto in diversi modi ...

Accesso tramite variabile ispettore

Questa è la più semplice. Crea semplicemente una variabile pubblica per GameObject, come abbiamo dimostrato in precedenza con i prefabbricati, e trascinala manualmente sul componente tramite l'ispettore. Quindi accedi alla variabile come sopra.

Accesso tramite tagging

Possiamo taggare GameObjects o prefabbricati tramite l'ispettore e quindi utilizzare le funzioni di ricerca dell'oggetto di gioco per individuare i riferimenti ad essi.

Questo viene semplicemente fatto come di seguito.

GameObject some_game_object = GameObject.FindGameObjectWithTag ("Brick");

Accesso tramite trasformazione

Se desideriamo accedere ai componenti in qualche oggetto genitore, possiamo farlo facilmente tramite l'attributo transform.

ComponentName comp = gameObject.transform.parent.GetComponent ();

Accesso tramite SendMessage

In alternativa, se vogliamo inviare un messaggio a molti altri componenti o se desideriamo inviare un messaggio a un oggetto che si trova in una gerarchia nidificata, possiamo usare le funzioni di invio messaggio, che accettano il nome della funzione seguito dagli argomenti.

gameObject.SendMessage ("MethodName", params); // Broadcast messagegameObject.SendMessageUpwards ("MethodName", params); // Ricevuto solo dai componenti che sono nidificati sopra.

Raycasting

Potresti averne sentito parlare prima quando le persone confrontano i giochi FPS che sono "basati sulla fisica" o "basati sui raggi". Il raycasting è essenzialmente come avere un puntatore laser che, quando entra in contatto con un "collisore" o "corpo rigido", restituisce un "colpo" e restituisce i dettagli dell'oggetto.

Ci sono due scenari in cui questo è utile (probabilmente ce ne sono molti altri):

  1. Se stavi progettando un sistema d'arma per un gioco, potresti usare il raycasting per il rilevamento dei colpi e persino personalizzare la lunghezza del raggio in modo che gli oggetti da mischia 'colpiscano' solo a breve distanza
  2. Crea un raggio dal puntatore del mouse a un punto nello spazio 3d, cioè se desideri che l'utente possa selezionare le unità con il proprio mouse in un gioco di strategia.

Come puoi vedere, il codice per questo è un po 'più complicato. La cosa fondamentale da capire è che per lanciare un raggio nel punto in cui il mouse punta nello spazio 3D richiede la trasformazione ScreenPointToRay. La ragione di ciò è che la fotocamera esegue il rendering di uno spazio 3D come una finestra 2D sullo schermo del laptop, quindi naturalmente è necessaria una proiezione per il trasferimento in 3D.

Rilevamento delle collisioni

In precedenza abbiamo menzionato i componenti Collider e Rigidbody che possono essere aggiunti a un oggetto. La regola per le collisioni è che un oggetto nella collisione deve avere un corpo rigido e l'altro un collisore (o entrambi hanno entrambi i componenti). Si noti che quando si utilizza il raycasting, i raggi interagiranno solo con oggetti con componenti del collisore collegati.

Una volta impostato all'interno di qualsiasi componente personalizzato collegato all'oggetto, possiamo utilizzare i metodi OnCollisionEnter, OnCollisionStay e OnCollisionExit per rispondere alle collisioni. Una volta ottenute le informazioni sulla collisione, possiamo rendere responsabile il GameObject e utilizzare ciò che abbiamo appreso in precedenza per interagire anche con i componenti ad esso collegati.

Una cosa da notare è che i corpi rigidi forniscono fisica come la gravità per gli oggetti, quindi se vuoi che questo sia disattivato dovrai controllare is_kinematic su.

Funzionalità avanzate

Non entreremo in nulla di tutto questo ora, ma forse in un articolo futuro, solo per farti capire che esistono.

Creazione di GUI

Unity ha un motore UI completo per la disposizione della GUI per il tuo gioco. In generale questi componenti funzionano in modo abbastanza simile al resto del motore.

Estensione di Unity Editor

Unity ti consente di aggiungere pulsanti personalizzati ai tuoi ispettori in modo da poter influenzare il mondo durante la modalità di modifica. Ad esempio, per aiutare con la costruzione del mondo potresti sviluppare una finestra degli strumenti personalizzata per la costruzione di case modulari.

Animazione

Unity ha un sistema di animazione basato su grafici che consente di fondere e controllare le animazioni su vari oggetti come i giocatori che implementano un sistema di animazione basato sulle ossa.

Materiali e PBR

Unity utilizza un motore di rendering basato sulla fisica che consente illuminazione in tempo reale e materiali realistici. La realtà è che dovrai prima imparare la modellazione 3D o utilizzare modelli realizzati e ottimizzati da qualcun altro prima di arrivare a questo, al fine di creare cose che abbiano un bell'aspetto.

Consigli per i nuovi arrivati

Se hai intenzione di scrivere il tuo primo gioco, non sottovalutare la complessità e il tempo necessari per scrivere anche il più banale dei giochi. Ricorda che la maggior parte dei giochi che escono su Steam hanno team che ci lavorano per anni a tempo pieno!

Scegli un concetto semplice e suddividilo in piccoli traguardi raggiungibili. Si consiglia vivamente di separare il gioco in componenti indipendenti il ​​più piccoli possibile, poiché è molto meno probabile che si verifichino bug se si mantengono i componenti semplici anziché blocchi di codice monolitici.

Prima di andare a scrivere qualsiasi codice per qualsiasi parte del gioco, vai a cercare ciò che qualcun altro ha fatto prima per risolvere lo stesso problema: è probabile che avranno una soluzione molto più semplice.

Belle risorse e comunità

Il design del gioco ha una delle migliori comunità in circolazione e ci sono molti professionisti altamente qualificati nel settore che pubblicano contenuti gratuitamente o quasi per niente. È un campo che richiede modellatori 3D, concept artist, game designer, programmatori e così via. Ho collegato alcune ottime risorse generali che ho trovato per ciascuno di questi campi di seguito:

Arte di concetto

  • Feng Zhu Design School (tutorial di concept art di oltre 90 ore)
  • Tyler Edlin Art (grande comunità artistica BST con feedback da professionisti sulle sfide mensili)
  • Art Cafe (interviste e seminari con famosi concept artist)
  • Trent Kaniuga (illustratore e artista 2D che sta anche realizzando il suo gioco)

Modellazione 3D

  • CG Cookie (Le migliori nozioni di base sulla modellazione della mesh in Blender Ever, hanno un sacco di altri contenuti eccellenti per Blender)
  • Tor Frick (modellatori e scultori di superfici dure in Blender)
  • Gleb Alexandrov (brevi potenti tutorial sul rendering in Blender)

Game Design

  • DoubleFine Amnesia Fortnight (GameDevs che fa un hackathon di 2 settimane e registra l'intero processo di progettazione)
  • GameMakers Toolkit (esamina i principi di progettazione del gioco)

Programmazione

  • Eroe fatto a mano (scrivere un gioco e un motore da zero in C)
  • Jonathan Blow (sviluppatore indipendente che trasmette in streaming il suo sviluppo del gioco)
  • Parentesi (tutorial di Nice Unity)

Conclusione

Spero che questo tutorial vi sia piaciuto! Faccio un po 'di lavoro di progettazione grafica e prototipi di giochi e interfaccia utente, quindi dai un'occhiata al mio portfolio ! Sono anche collegato a .

Portafoglio| LinkedIn