Perspektywa pierwszoosobowa- animacje

W tym temacie zajmiemy się komponentem animatora, który pozwala kontrolować animacje oraz przejścia pomiędzy nimi w ruchu obiektów 3d. Temat jest rozwinięciem poprzedniego (zobacz)

Kliknij na obrazku aby zobaczyć krótki film dotyczący tego tematu

Animator Unity

Animacja postaci

Stosowanie animacji bardziej zaawansowanych wymaga użycia tak zwanych szkieletów- systemu dźwigni z przegubami (odpowiednik stawu układu kostnego). Taki szkielet z siatką, teksturą i animacjami należy przygotować w zewnętrznym programie- na przykład w Blenderze.

animacja Unity

Gotowy model wraz teksturami, szkieletem i animacjami eksportujemy do pliku *.fbx

animacje fbx Blender Unity

Parametry importu

Po imporcie pliku *.fbx można sprawdzić czy animacje się dobrze zaimportowały. I usunąć te niewłaściwe. Wybrać czy animacja ma się powtarzać w czasie (na przykład bieganie, chodzenie itp.)

import animacji Unity

Nie zapomnij zapisać zmian klawiszem Apply, który znajduje się w dole otwartej karty importu.

Po imporcie pliku *.fbx na scenę dodajemy pusty obiekt (Create Empty). Obiekt ten będzie rdzeniem postaci. Nadajemy mu dowolną nazwę (ja nadałem dziki). Do obiektu dodajemy system kości i siatki postaci z zaimportowanego pliku fbx. Po utworzeniu wstępnego prefabrykatu w edytorze Unity powinny być widoczny układ kości, których nazwy są takie jakie przypisałeś w Blenderze.

create empty animacja Unity

Ten system kości pozwala utworzyć alternatywne animacje z poziomu Unity. System tworzenia animacji z poziomu Unity jest dużo prostszy niż na przykład w Blenderze, ale nie daje takich samych możliwości.

Do rdzenia postaci dodajemy komponent Charakter Controler, skrypt RuchBohatera (skrypt jest z poprzedniego tematu zobacz) i komponent Animator.

Charakter Controler animacja Unity

Na tę chwilę Animator nie będzie działać, dopóki nie utworzymy kontrolera animatora.

Kontroler animacji

Tworzymy kontrolera animacji dla postaci. Ja przypisałem nazwę Dziki

Animator Kontroler Unity

Do prefabrykatu postaci dodajemy komponent animatora (Animator). Do animatora podpinamy kontrolera animacji. Animator Kontroler Unity

Klikamy dwa razy szybko w nazwę podpiętego kontrolera animatora i przenosimy się do okna edycji kontroler animatora. Więcej zobacz

Tworzymy węzły stanów animacji.

węzły animacj Unity

Dodajemy połączenia pomiędzy węzłami. Węzłom przypisujemy unikatowe tagi oraz klipy animacji, które będą w nich odtwarzane. Prędkości animacji dobierzemy późnej po uruchomieniu sceny i skryptów animacji.

węzły i połaczenia animacj Unity

Końcowy układ węzłów animacji przygotowany dla mojej postaci ma poniższy wygląd

węzły animacj Unity

Jeszcze raz sprawdź czy wybrane klipy animacji mają przypisaną pętlę czasową. Pętla animacji pozwala wielokrotnie odtwarzać animowany stan na przykład chodzenia.

pętla animacj Unity

Kliknij Apply aby uaktualnić

Jeżeli teraz uruchomisz scenę, do której dodasz tworzony prefabrykat, to zobaczysz odtwarzaną animację przypisaną do pierwszego węzła.

Wyzwalacze animacji

Wyzwalacze animacji to układ parametrów, które są zmieniane programowo i pozwalają przełączać aktywny węzeł animacji. Do dyspozycji jest cztery typy wyzwalaczy. My tworzymy jeden typu Int przypisując mu nazwę intStanAnimacji.

wyzwalacze animacj Unity

Przez wartość tej zmiennej będziemy przełączać aktywność węzłów animacji.

Na przykład przejście ze stany CZEKAJ na BIEG edytujesz po kliknięciu myszką w wybrana linię przejścia (standardowo podświetli się na niebiesko)

edycja animacj Unity

Takie ustawienia pozwolą na przerwanie bieżącej animacji i przejście do następnej bez czekania aż się skończy odtwarzać bieżąca (ustaw przerwanie na Next State Then Current State). Ustaw warunki przejścia. Tu przyjęliśmy, że bieg gdy intStanAnimacji=2.

Czynność powtórz dla każdej linii przejścia.

Zwróć uwagę na uniwersalność Any States.

Any States animacj Unity

Ten układ tak się interpretuje: animacja stanu Skok jest dostępną z każdej innej animacji i po zakończeniu przechodzi do stanu Czekaj

Skrypt animacji

Sposób wywołania przejść pomiędzy animacjami jest dowolny. Poniżej zaprezentuje skrypt, który wykorzystuje typ wyliczeniowy zdefiniowany jak poniżej

Wskazówka:


    //typ wyliczeniowy dla animacji
    public enum STAN_ANIMACJI { 
                         CZEKAJ,//stan 0
                         SPACER,//stan 1
                         BIEG,//stan 2
                         CZOLGANIE,//stan 3
                         SKOK//stan 4
                         }

Używanie typu wyliczeniowego ułatwi orientacje w kodzie, po prostu nazwy kojarzą się z funkcją przejścia animacji. Dodatkowo do opcji projektu dodamy trzy klawisze. Uruchom Input Manager (menu Edit/ Project Settings/ Input Manager). Zwiększ rozmiar tablicy Axes o 3. Zdefiniuj nowe elementy jak poniżej, w których klawisz b to bieg, c to czołganie, s to spacer. Patrz poniżej.

enum animacj Unity

W edytorze Unity utwórz nowy skrypt o nazwie AnimacjaDzikiego (lub każdej innej jak ci odpowiada) i wypełnij poniższym kodem

Wskazówka:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimacjaDzikiego : MonoBehaviour
{
    //typ wyliczeniowy dla animacji
    public enum STAN_ANIMACJI { 
                         CZEKAJ,//stan 0
                         SPACER,//stan 1
                         BIEG,//stan 2
                         CZOLGANIE,//stan 3
                         SKOK//stan 4
                         }
    public float wspolczynnikZmianyPredkosci = 1;
    Animator animator;
    STAN_ANIMACJI stanAnimacji = STAN_ANIMACJI.CZEKAJ;
    
    public STAN_ANIMACJI StanAnimacji
    {
        get { return stanAnimacji; }
        set { 
              stanAnimacji=value;
              //ustwa stan animacji z indeksu aktywnego typu wyliczeniowego
              animator.SetInteger("intStanAnimacji", (int)stanAnimacji);
            }
    }
    // Start is called before the first frame update
    void Start()
    {
        animator = GetComponent<Animator>();
    }

public void PrzelaczAnimacje(float _constV)
    {
        if (Input.GetAxis("Spacer") != 0)
        {
            StanAnimacji = STAN_ANIMACJI.SPACER;
            //ustaw predkośc na stała
            wspolczynnikZmianyPredkosci = _constV;
        }
        if (Input.GetAxis("Bieg") != 0)
        {
            StanAnimacji = STAN_ANIMACJI.BIEG;
            //zwiększ predkośc podczas biegu 2.5 razy
            wspolczynnikZmianyPredkosci = 2.5f* _constV;
        }
        if (Input.GetAxis("Czolgaj") != 0)
        {
            StanAnimacji = STAN_ANIMACJI.CZOLGANIE;
            //zmniejsz prędkośc podczas czołgania 2 razy
            wspolczynnikZmianyPredkosci = 0.5f* _constV;
        }
    }
    

    // Update is called once per frame
    void Update()
    {
        
    }
}

Skrypt dołącz do postaci

Any States animacj Unity

Zmiany w skrypcie RuchBohatera

W skrypcie ruchu, który został napisany w poprzednim temacie musimy dokonać kilku zmian aby można sterować animacjami. Zacznij od dodania nowej zmiennej constV

Wskazówka:


//współczynnik prędkości
    const float constV = 2.5f;
    public float v= constV,
                 wysSkoku=2.0f;

Kolejne zmiany dotyczą funkcji Skok(), Spadaj(), Ruch(). Poniżej pełna zawartość tego skryptu po modyfikacji.

Wskazówka:


using System.Collections;
using System.Collections.Generic;
using Unity.Android.Gradle.Manifest;
using UnityEngine;
using static AnimacjaDzikiego;

public class RuchBohatera : MonoBehaviour
{
    public CharacterController kontroler;
    public Transform kamera;
    private bool fGrunt;
    //przyspieszenie grawitacyjne
    public float g = -9.8f;

    //współczynnik prędkości
    const float constV = 2.5f;
    public float v= constV,
                 wysSkoku=2.0f;
    Vector3 wektorPredkosci = Vector3.zero;
    public float wygladzenie = 0.1f;
    float buforBiezacegoWygladzania;
    


    public void Skok()
    {
        if (fGrunt && Input.GetAxis("Jump") != 0)
        {
            //v=Pierwiastek(2gh)
            wektorPredkosci.y = Mathf.Sqrt(-2f * g * wysSkoku);
            GetComponent<AnimacjaDzikiego>().StanAnimacji 
                              = STAN_ANIMACJI.SKOK;
        }
    }

    void Spadaj()
    {
        wektorPredkosci.y += g * Time.deltaTime;
        if (fGrunt && wektorPredkosci.y < 0)
        {
            //nie spadaj szybciej niż 54m/s
            wektorPredkosci.y = -54f;
        }
        kontroler.Move(wektorPredkosci * Time.deltaTime);
    }
    void Ruch()
    {
        float poziom = Input.GetAxis("Horizontal");
        float pion = Input.GetAxis("Vertical");
        Vector3 kierunek = new Vector3(poziom, 0, pion).normalized;
        //czy ruch, powiedzmy wiecej niż 5 centymetrów
        if (kierunek.magnitude >= 0.05f)
        {
            //obrót postaci
            //zwróc kąt w radianach z płaszczyzny 2D- oś X a Z
            //zamień radiany na stopnie
            float katPatrzenia = Mathf.Atan2(kierunek.x, kierunek.z)
                                 *Mathf.Rad2Deg+
                                 kamera.eulerAngles.y;
            //wygladzaj obrot,
            //predkosc wygladzania wyslij do bufora
            float kat = Mathf.SmoothDampAngle(
                      transform.eulerAngles.y,
                      katPatrzenia,
                      ref wygladzenie,
                      buforBiezacegoWygladzania
                      );
            transform.rotation = Quaternion.Euler(0, kat, 0);
            Vector3 kierunekRuchu = Quaternion.Euler(0, katPatrzenia, 0)
                                    *Vector3.forward;
            kontroler.Move(kierunekRuchu.normalized * v * Time.deltaTime);
            //jest ruch to domyslnie ustawiaj na spacer
            if (GetComponent<AnimacjaDzikiego>().StanAnimacji == STAN_ANIMACJI.CZEKAJ)
              {
                GetComponent<AnimacjaDzikiego>().StanAnimacji = STAN_ANIMACJI.SPACER;
                GetComponent<AnimacjaDzikiego>().wspolczynnikZmianyPredkosci = constV;
              }
            GetComponent<AnimacjaDzikiego>().PrzelaczAnimacje(constV);
            v = GetComponent<AnimacjaDzikiego>().wspolczynnikZmianyPredkosci;
        }
        else
        {
            //pozostałe animacje przełacz
            //w skrypcie AnimacjaDzikiego
            GetComponent<AnimacjaDzikiego>().StanAnimacji = STAN_ANIMACJI.CZEKAJ;
        }
    }
    
    // Start is called before the first frame update
    void Start()
    {
        //blokuj kursor na srodku ekranu
        Cursor.lockState = CursorLockMode.Locked;
        //ukryj kursor
        //standardowo klawisz Esc przywróci widok kursora
        Cursor.visible = false;
    }

    // Update is called once per frame
    void Update()
    {
        //sprawdzaj czy jestes nad dowolnym podlozem
        fGrunt = kontroler.isGrounded;
        Ruch();
        Skok();
        Spadaj();
    }
    
}

Uruchom scenę i sprawdź działanie skryptów.

animacja chodzenia Unity

Postać powinna reagować na bieganie, skakanie i czołganie.

Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Olinowanie stałe- kalkulator średnic

Olinowanie stałe- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
przepis na gogfry

Przepis na gofry

zobacz
przepis na bitą śmietanę

Przepis na bitą śmietanę

zobacz