L’animazione è una componente essenziale dei videogiochi. Gran parte dei videogiochi cerca di simulare il mondo reale; per questo è indispensabile riuscire a rappresentare il movimento delle persone, delle automobili, degli animali e degli oggetti in generale, nel modo più verosimile possibile. In questo articolo descriveremo alcuni concetti relativi all’animazione nei videogiochi facendo riferimento in particolare all’animazione degli sprite nel motore Unity 2D.


1) L’animazione e il movimento degli oggetti

Possiamo definire l’animazione un cambiamento nel tempo di una certa proprietà di un oggetto, ad esempio la posizione, l’orientamento, lo stato di moto, il colore, le dimensioni, ecc. Il tempo, il movimento e il cambiamento di alcune proprietà hanno un ruolo centrale in ogni fenomeno di animazione.
L’idea che sta alla base dell’animazione è di visualizzare una serie di immagini con una velocità abbastanza alta, in modo che il cervello umano la interpreti come un flusso continuo, e non discreto, grazie al fenomeno della persistenza della visione.
La teoria della persistenza della visione, proposta già da Lucrezio (94 – 56 a.c.) nella sua opera ‘De Rerum Natura’, sostiene che l’occhio mantiene l’impronta di un immagine nella retina per un breve istante, anche dopo che lo stimolo esterno è cessato. L’ipotesi della persistenza della visione è stata messa in discussione da altre teorie, in particolare dall’ipotesi del fenomeno PHI proposta da Max Wertheimer nel 1912. Questa teoria sostiene che il nostro cervello è in grado di connettere gli intervalli di tempo vuoti in una successione di immagini statiche, dando l’illusione del movimento. Sostanzialmente il nostro cervello avrebbe una capacità innata di percepire il movimento e in generale di dare senso ad immagini anche se non sono complete.
Per uno studio approfondito dell’argomento della visione si possono consultare i seguenti testi: [1] oppure [2].


2) L’animazione tramite computer

Il tempo ha un ruolo centrale nell’animazione e in generale nella simulazione del movimento. Il tempo fisico è il tempo del mondo reale ed è una variabile continua. Le simulazioni tramite computer invece gestiscono solo dati discreti. La pipeline grafica effettua il rendering delle immagini ad intervalli discreti; in ogni animazione le proprietà degli oggetti cambiano in istanti temporale ben precisi. Possiamo quindi distinguere due tipologie di tempo:

  • tempo reale fisico
  • tempo del gioco

Il tempo del gioco è costituito da intervalli discreti, gestiti dal game loop che effettua gli aggiornamenti periodici dello stato degli oggetti sulla scena (per una descrizione del game loop vedere il link). Nei videogiochi le immagini che appaiono sulla scena sono preparate mediante frame che vengono aggiornati con frequenza elevata, ad esempio 30 fps o 60 fps (frames per second).
Mentre nel mondo reale dove il tempo è continuo possiamo osservare i vari eventi in ogni particolare momento, nei videogiochi e in generale nelle simulazioni tramite computer gli eventi avvengono in momenti discreti all’interno dei frame.
La preparazione di ogni frame richiede che vengano aggiornati i dati relativi ad ogni oggetto sulla scena:

  • posizione
  • orientamento
  • forma geometrica
  • fattore di scala
  • aspetto (colore, materiale, illuminazione, ecc.)
  • stato fisico
  • ecc.

2.1) I fotogrammi chiave (keyframes)

Abbiamo visto che i frame sono i luoghi nei quali avvengono eventuali cambiamenti degli oggetti sulla scena del gioco, anche se ovviamente molti frame possono esistere senza cambiamenti rispetto ai frame precedenti. Dato il numero enorme dei frame sarebbe del tutto impraticabile definire manualmente i cambiamenti per ognuno di essi. L’animazione tramite computer permette di definire alcuni frame di riferimento (keyframes), che definiscono momenti significativi del processo di animazione, e il programma genera automaticamente la sequenza di animazione. Un keyframe è come un fotogramma che contiene le informazioni sulla posizione, rotazione, scala, ecc. dell’oggetto animato. Ad esempio nel caso dell’animazione di una sbarra automatica per il controllo dell’accesso ad un parcheggio, possiamo definire due stati, uno con la sbarra abbassata e un altro con la sbarra completamente alzata. Questi due stati indicano l’inizio e la fine dell’animazione. Il motore grafico (ad esempio Unity), mediante un procedimento matematico di interpolazione, è in grado di preparare i frame intermedi (tweens), i quali messi insieme costituiscono una sequenza che da l’illusione del collegamento continuo senza scatti fra i keyframe.

2.2) Tipi di animazione

Esistono diverse tipologie di animazioni. Alcune possono essere create direttamente in Unity tramite il prodotto Unity Animation Editor, mentre altre vengono create tramite prodotti esterni, come Photoshop, Blender, Maya, 3ds Max, Gimp, e poi importate nel progetto Unity. Esiste anche la possibilità di creare un’animazione tramite il codice; in questo caso l’animazione in genere non viene creata in anticipo, ma viene gestita durante il gioco, in funzione degli eventi.

Animazione di un corpo rigido
In questo caso un oggetto, ad esempio una porta, viene considerato come un unico e indivisibile, senza parti che si muovono in modo indipendente. I cambiamenti sono relativi soltanto alla posizione, all’orientamento ed eventualmente alla scala.

L’animazione scheletrale (skeletal animation)
In questo tipo di animazione bisogna considerare anche il movimento delle singole componenti. Questo tipo di animazione è il più utilizzato nei giochi. La skeletal animation è una tecnica di animazione nella quale un oggetto articolato (un personaggio ad esempio) è composto da due parti: una parte superficiale (mesh o skin) utilizzata per rappresentare l’oggetto e una struttura gerarchica di ossa (bones) interconnessi, ognuno con le sue proprietà. Il sistema di animazione produce delle pose (o keyframe) per ogni osso della struttura e il motore di animazione mediante un processo di interpolazione collega i vari keyframe. Viene chiamato rigging il processo di creazione del legame fra la mesh e la gerarchia delle ossa e dei collegamenti.
L’animazione scheletrale non è limitata al corpo umano, ma può essere applicata a molte situazioni: un’automobile, una navicella spaziale, un soldato, una porta, ecc.

Animazione degli sprite
Uno sprite è un’immagine grafica bitmap che in genere fa parte di una scena più grande. Può essere statica oppure può essere animata. Una sequenza di sprite può essere visualizzata tramite i frame ad una velocità opportuna per dare la sensazione del movimento continuo.

Animazione tramite morphing
Si tratta di una tecnica per passare in modo continuo da un’immagine ad un altra, trasformando i vertici della figura iniziale in quella finale. In ogni keyframe dell’animazione i vertici sono messi in posizioni differenti, avvicinandosi ai vertici dell’immagine di arrivo. Questa modalità di animazione permette un maggiore controllo sul movimento degli oggetti.

Animazione basata sul motore fisico (physics based animation)
In alcune situazioni l’animazione basata sul motore fisico può produrre fenomeni più realistici dell’animazione basata sui keyframe. Il motore fisico di Unity permette di simulare in modo efficiente molti fenomeni del mondo reale, come gli effetti della gravità, la presenza del vento o del mare in tempesta, ecc.

Per un approfondimento sulle tipologie di animazione vedere [3].


3) L’animazione in Unity

Unity ha un sistema di animazione chiamato Mecanim.  Per gestire il processo di animazione, Mecanim utilizza lo strumento della macchina a stati finiti: ad ogni stato corrisponde un’animazione ed è possibile definire le transizioni fra i vari stati. Per ogni transizione da uno stato ad un altro Mecanim è in grado di effettuare le interpolazioni fra i frame, in modo da ottenere una sequenza fluida e naturale. Il sistema inoltre permette di gestire la sovrapposizione di diverse animazioni, necessarie per le strutture complesse.
Per creare l’animazione di un GameObject sono necessari tre componenti:

  • un componente Animator per il GameObject
  • un Animator Controller
  • almeno una clip di animazione (Animation Clip)

Vediamo ad esempio come si crea l’animazione di un singolo oggetto, modificando alcune delle proprietà dell’oggetto stesso: la posizione, la rotazione, la scala o il colore.

3.1) Creazione di una clip di animazione di un oggetto

I passi per creare una singola clip di animazione sono i seguenti:

  • creare una nuova scena;
  • creare un oggetto (ad esempio un cubo 3D);
  • nel menù Window scegliere l’opzione “Animation”;
  • cliccare sul bottone “Create” e dare un nome all’animazione (file con estensione .anim);
  • cliccare sul bottone “Add Property”. Qui si può scegliere il tipo di animazione specificando la proprietà che deve cambiare: la posizione, la rotazione, la scala oppure le proprietà del Mesh Renderer (ad esempio il colore).

Quando si preme il bottone “create” Unity effettua diverse azioni. In primo luogo crea un “Animator Controller” per l’oggetto (file con estensione .controller). Quindi aggiunge un “Animation” su questo controller. Poi aggiunge un componente “Animator” all’oggetto, visibile nell’Inspector.
Naturalmente possono essere definite più animazioni sullo stesso oggetto. Nell’esempio seguente possiamo vedere 3 tipi di animazioni, con tre proprietà che variano: la posizione, l’orientamento e il colore.

Esempio di animazione multipla

Per un maggiore dettaglio vedere la documentazione online di Unity.

3.2) Dopesheet e curve di animazione

La finestra di animazione (Animation Window) supporta due modalità operative diverse per creare e modificare la clip di animazione:

  • Dopesheet mode
  • Curves mode

Nella modalità Dopesheet è possibile impostare in modo preciso i keyframe e i valori delle proprietà variabili (posizione, rotazione, colore, ecc.). Il Dopesheet offre una visione compatta dei momenti temporali nei quali le proprietà cambiano valore. Tuttavia è difficile avere una idea precisa dei valori delle varie proprietà negli intervalli di tempo compresi fra i keyframe.
La modalità Curves permette di avere maggiore controllo sui valori delle proprietà in ogni istante di tempo. L’editor per la gestione delle curve (Curve Editor) permette di creare e modificare le curve. Una curva di animazione ha una pluralità di chiavi, che sono dei punti di controllo dell’animazione. Le curve di animazione hanno diversi colori per rappresentare i valori delle varie proprietà oggetto dell’animazione.

Curve di animazione

4) Animazione degli sprite sheets in Unity 2D

Nella version 4.3 Unity ha introdotto la possibilità di scegliere l’opzione 2D e sono stati aggiunti gli oggetti Sprite, che contengono un’immagine bitmap (Texture2D). Uno sprite 2D è un’immagine grafica che può essere usata come oggetto bidimensionale con coordinate (x,y). Uno sprite in Unity è definito da un rettangolo, una Texture2D e un punto pivot.
Lo sprite può rappresentare un singolo oggetto o un’intera scena. Inoltre diversi sprite possono essere combinati per creare un singolo oggetto.
Gli sprite possono essere creati direttamente tramite Unity oppure importati negli assets del progetto, e possono essere dotati di movimento. Se si apre un progetto Unity nella modalità 2D ad ogni immagine importata nel progetto viene assegnato il tipo texture Sprite (2D e UI).

4.1) Sprite Renderer

Quando viene creato un GameObject Sprite, Unity crea anche il componente SpriteRenderer associato, che ha il compito di effettuare il rendering dello sprite stesso. Mentre in ambiente 3D l’aspetto di un oggetto è diverso a seconda dell’illuminazione e della posizione della telecamera, nello spazio 2D l’oggetto viene rappresentato senza alcuna profondità. Con lo Sprite Renderer è possibile impostare varie proprietà come il materiale, il colore, il layer, ecc.

4.2) Gli sprite sheets

Spesso è più conveniente registrare in una unica immagine una collezione di sprite. L’idea è di creare un’unica immagine che contiene tutte le animazioni di un oggetto. Questa immagine viene chiamata sprite sheet (o sprite atlas). Unity fornisce uno strumento, lo Sprite Packer, per unire gli sprite individuali in un unico atlante.
Un’alternativa è quella di disegnare gli sprite e creare l’animazione con uno dei tanti prodotti presenti nel mercato (Photoshop, Blender, Gimp, Maya, 3ds Max) . In questo modo si può verificare e provare l’animazione, semplificando la complessità del progetto. Poi si procede ad effettuare l’import negli assets del progetto Unity impostando lo Sprite Mode nell’inspector a Multiple. Quindi mediante lo Sprite Editor di Unity si procede a separare le singole immagini con tre diverse modalità:

  • Automatic
  • Grid by cell size
  • Grid by cell count
Unity Sprite Editor

4.3) Animazione di una collezione di sprite

Un modo semplice per creare un’animazione a partire da uno sprite sheet consiste nei seguenti passi:

  • importare la collezione degli sprite, ad esempio nel formato .png;
  • fare lo split dell’atlante nei singoli sprite mediante lo Sprite Editor; a questo punto nel Project View viene mostrata una freccia sulla sprite importata, per indicare che si tratta di una collezione di sprite;
  • selezionare gli sprite che fanno parte di una sequenza di animazione completa e trascinarli (drag and drop) sul pannello Gerarchia (Hierarchy Window). Unity aprirà un dialogo per creare e salvare l’animazione su un file con estensione .anim. Un oggetto sprite viene creato sulla scena. Contestualmente Unity crea anche l’Animator controller e aggiunge il componente Animator all’oggetto. Eseguendo il gioco eseguirà tutte le immagini della sequenza;
  • se necessario modificare i parametri dell’Animation controller per regolare la velocità, il looping dell’animazione, i keyframe, ecc.;
  • per muovere l’oggetto preparare uno script associato ad esso.

La seguente immagine presenta una semplice animazione di uno spritesheet. Uno script associato gestisce il movimento orizzontale e l’urto con le pareti laterali.

Animazione tramite spritesheet

Naturalmente si possono fare animazioni più complesse. Un esempio classico è quello di avere varie collezioni di sprite relativi a diversi stati di un personaggio: idle, walk, run, attack, die. Per ognuna delle collezioni si crea una diversa animazione. Ogni animazione corrisponde ad un diverso stato e queste animazioni possono essere coordinate da un Animator Controller, che non è altro che una macchina a stati finiti, come vedremo in seguito.
Per un approfondimento sull’animazione con Unity vedere [4] oppure [5].


5) Animator come macchina a stati finiti

Come abbiamo visto le macchine a stati finiti sono parte del sistema di animazione di Unity. Tuttavia possono essere implementate anche senza che sia presente l’animazione.
L’Animator del sistema di animazione Mecanim è di fatto una macchina a stati finiti, in grado di gestire differenti stati e passare da uno stato all’altro mediante delle transizioni. I passi per controllare il comportamento di un oggetto mediante una semplice macchina a stati finiti basata sull’Animator di Unity sono i seguenti:

  • creare un GameObject;
  • creare un Animator Controller;
  • definire gli stati, le transizioni e i parametri;
  • creare gli script di Behaviour associati agli stati;
  • nello script associato al GameObject inserire la gestione dei parametri da comunicare all’Animator (ad esempio controllo dei colori del semaforo, oppure della distanza di un player, ecc).

L’immagine seguente è un semplice esempio di animazione ottenuta utilizzando l’Animator come macchina a stati finiti. Un oggetto, in questo caso una palla, può essere in tre stati diversi: fermo, velocità bassa, velocità alta, in funzione del colore del semaforo. Sono definite tre transizioni per il passaggio da uno stato all’altro quando c’è un cambiamento nel semaforo. Nonostante la sua semplicità l’esempio contiene gli ingredienti essenziali di ogni macchina a stati finiti: un oggetto che può trovarsi in diversi stati e passa da uno stato all’altro in funzione di cambiamenti nell’ambiente esterno.
Naturalmente al posto della palla si possono utilizzare altri oggetti più interessanti: un personaggio che regola il suo stato di moto in funzione del semaforo, un’automobile, un dispositivo meccanico, ecc.

Animator e macchina a stati finiti
Diagramma degli stati

Conclusione

L’animazione è un argomento complesso e fondamentale per lo sviluppo di videogiochi interessanti e sofisticati, che siano in grado di simulare in modo efficace il mondo reale. In articoli successivi approfondiremo le varie tipologie di animazione e descriveremo in particolare gli strumenti matematici che stanno alla base dei sofisticati algoritmi utilizzati nei moderni videogiochi.


Bibliografia

[1]V. Bruce, M. Georgeson, P. Green – Visual Perception: Physiology, Psychology and Ecology (Psychology Press)

[2]D. Hubel – Eye, Brain, and Vision (Freeman & Co)

[3]Jason Gregory – Game Engine Architecture (CRC Press, 2014)

[4]A. Godbold, S. Jackson – Mastering Unity 2D Game Development (Packt)

[5]A. Thorn – Unity Animation Essentials (Packt)


0 commenti

Lascia un commento!