Archivio ScriptsImparare UnityTips

Animazioni in sequenza

Può capitare di voler fare delle animazioni in sequenza usando un solo tasto, come avviene per alcuni giochi d’azione/RPG dove il giocatore premendo il tasto di attacco esegue un tipo di attacco basilare e finito, ma se esso preme il pulsante di attacco ripetutamente, il personaggio, dopo il primo attacco basilare, continua ad attaccare eseguendo animazioni diverse e più complesse. Si tratta si una serie di animazioni concatenate che sono legate all’animazione in esecuzione e in fase di conclusione.

COSA FAREMO E PERCHE’

Come nella maggior parte dei casi, esistono svariati approcci e tipologie di soluzione per raggiungere questo scopo.
Noi ne vedremo uno tra i più semplici, ovvero quello che presuppone una conoscenza di livello base dell’Animator che sarebbe lo strumento (Finite State Machine) che gestisce le animazioni in Unity.
L’Animator di Unity è uno strumento potentissimo che rappresenta uno dei pilastri dell’engine. Ma come avrete sentito dire altrove; “la potenza è nulla senza controllo”. Essendo uno strumento di per se abbastanza complesso, è necessario studiarne il funzionamento con diverse lezioni. Dunque adesso noi andremo ad usare una soluzione che delega il controllo al codice in C# (che già dovremmo conoscere abbastanza bene).

Andremo a controllare quale animazione è in esecuzione durante la pressione del tasto Fire01” tramite codice, poi controlleremo anche a che punto si trova questa animazione (ovvero se sta per terminare) e andremo a far eseguire l’animazione che ne consegue tramite un CrossFade, ovvero un passaggio graduale dall’animazione in corso ad un’animazione successiva.

In alternativa si potrebbero usare dei valori (float, string, bool) da inviare all’Animator con un’istruzione tipo “aminatore.SetFloat(nomeValore,valore)” che ne influenzino il comportamento, delegando la maggior parte del lavoro all’Animator. Ma per far questo dovremmo conoscere uno strumento che non ho ancora trattato su queste pagine.
Ovviamente siete qui per imparare e devo presupporre un grado di conoscenza di Unity di livello basilare da parte di chi legge. Per questo motivo vedremo la prima soluzione, quella che secondo me è la più facile implementare e che necessita una conoscenza meno approfondita dell’Animator e che delega la maggior parte del lavoro allo script in C#.
L’argomento Animator sarà ripreso e approfondito in sede opportuna.

INIZIAMO

Se non lo abbiamo già, creiamo un Animator per il nostro personaggio e poniamo le nostre animazioni di attacco al suo interno.
Non sarà necessario nessun passaggio (Transitions) tra lo stato di riposo a quello di attacco, perché tale passaggio le effettueremo da codice. Sarà necessario solo il passaggio inverso, ovvero dai vari stati di attacco allo stato di “Riposo” (o il vostro stato di default che di norma potrebbe e dovrebbe essere un Blend Tree).
Non sarà necessario neanche specificare dei parametri particolari per il passaggio tra uno stato ad un altro. Semplicemente, al termine di una qualsiasi animazione di attacco, se non verrà premuto di nuovo il pulsante di Fire01 durante l’esecuzione di una delle animazioni di attacco, lo stato tornerà automaticamente su “Riposo“.

Ed ecco il codice da usare per effettuare gli attacchi in sequenza.

//Unity3DTutorials.it
using UnityEngine;

public class AttackAnimation : MonoBehaviour {

    public Animator animator; //Il nostro Animator
    AnimatorClipInfo[] currentClipInfo; //Le info necessarie per capire quale animazione è in esecuzione
    public float clipNormalizedTime; //Il timer normalizzato (cioè da 0 a 1) del clip in esecuzione



    void Update () {

        currentClipInfo = animator.GetCurrentAnimatorClipInfo(0); //Teniamo aggiornato le info del Clip in esecuzione
        clipNormalizedTime= animator.GetCurrentAnimatorStateInfo(0).normalizedTime; //Teniamo aggiornato lo stato del Clip in esecuzione


        
        if (Input.GetButtonDown("Fire1"))//Se premuto il tasto Fire1
        {


            if (currentClipInfo[0].clip.name.Equals("Riposo")) //Se in questo momento è in esecusione l'animazione Riposo, esegui l'animazione Attack01
            { 
                    animator.CrossFade("Attack01", 0.1f); //Esegue l'animazione Attack01
            }

            else if (currentClipInfo[0].clip.name.Equals("Attack01"))  //Se in questo momento è in esecusione l'animazione Attack01, esegui l'animazione Attack02
            {
                if (clipNormalizedTime > 0.75f) //Se l'animazione Attack01 è giunta almeno a tre quarti della sua esecuzione
                    animator.CrossFade("Attack02", 0.1f);//Esegue l'animazione Attack02
            }

            else if (currentClipInfo[0].clip.name.Equals("Attack02")) //Se in questo momento è in esecusione l'animazione Attack02, esegui l'animazione Attack03
            { 
                if (clipNormalizedTime > 0.75f) //Se l'animazione Attack02 è giunta almeno a tre quarti della sua esecuzione
                    animator.CrossFade("Attack03", 0.1f);//Esegue l'animazione Attack03
            }

        }
 
    }
}

 

Come sempre il codice è commentato in ogni sua riga e istruzione, così che sia di facile comprensione.
Per chiarire l’uso dell’istruzione
if(clipNormaliedTime >0.75f)
spieghiamo che:
clipNormaliedTime è il tempo normalizzato, ovvero indica il timer del clip in corso, dove 0 è l’inizio e 1 è la fine.
Dunque quando il clip sarà a 0.5 significa che si trova alla metà esatta della sua esecuzione totale, mentre quando si trova a 0.75 significa che si trova a tre quarti della sua esecuzione totale.
In questo modo potrete controllare al millesimo di secondo il momento in cui volete che la successiva animazione dell’attacco sia eseguita.
E’ altresì ovvio che potrete aggiungere una quantità infinita di animazioni nella vostra sequenza.

Potete scaricare il package di esempio funzionante (versione Unity 2018 2.2f1) che ho usato per testare questo sistema e che contiene tutto il necessario (attenzione al copyright sul modello del personaggio )da questo link: MultipleAnimationSequence.unitypackage

Un pensiero su “Animazioni in sequenza

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *