5. Controlul personajelor

Cerinte

Realizati un personaj animat, controlat de la tastatura cu urmatoarele detalii:

  • camera 3rd person
  • se poate misca si roti
  • are animatie de
    • idle: cand sta pe loc,
    • mers: cand are o deplasare controlata pe WASD
    • alergat: cand e tinuta apasata tasta SHIFT + deplasare
    • Jump: la apasarea tastei SPACE

Documentatie video

Inregistrare pe Teams

Documentatie extinsa text

Controlul personajelor in 3D

Pentru miscarea si controlul caracterelor in 3D sunt posibile mai multe abordari.

CharacterController

CharacterController este o componenenta ce poate fi adaugata pentru a putea controla personajul. Aceasta componenta nu foloseste elemente de fizica in nici nu fel, dar vine atasat cu un collider de baza Capsule Collider care nu permite intrarea in alte collidere. Acest lucru simplifica foarte mult scriptarea caracterului.

Character Controller pune la dispozitie doua metode pentru miscarea caracterului:

  • SimpleMove(Vector3 speed) care va misca caracterul tinand cont de gravitatia definita, dar in care axa Y este ignorata
// Move forward / backward
        Vector3 forward = transform.TransformDirection(Vector3.forward);
        float curSpeed = speed * Input.GetAxis("Vertical");
        controller.SimpleMove(forward * curSpeed);
  • Move(Vector3 motion) care va muta caracterul in functie de paracmetrul motion, care reprezinta miscarea absoluta, astfel ca acceleratii de genul gravitatiei vor trebui implementate manual.
   moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection = moveDirection * speed;
 
            if (Input.GetButton("Jump"))
            {
                moveDirection.y = jumpSpeed;
            }
        }
 
        // Apply gravity
        moveDirection.y = moveDirection.y - (gravity * Time.deltaTime);
 
        // Move the controller
        controller.Move(moveDirection * Time.deltaTime);

In cazul functiilor puse la dispozitie de Character Controller, miscarile sunt constranse de coliziuni in mod automat si este destul de permisiva (spre exemplu va putea urca autmat rampe sau scari).

Rigidbody

Componenta de Rigidbody practic determina ca obiectul pe care e plasata sa se comporte ca un corp fizic, care interactioneaza cu mediul si asupra caruia se pot aplica forte fizice. Implicit, componenta Rigidbody este afectata de gravitatia definita ca prametru.

Exista 4 moduri in care se poate aplica o forta:

  • Force: adauga o forta continua si dependenta de masa
  • Acceleration: adauga o acceleratia continua independenta de masa
  • Impulse: adauga o forta instanta si dependenta de masa
  • VelocityChange: adauga o velocitate instanta independenta de masa

Pentru a adauga o forta exista de asemenea mai multe metode, dar cea standard este AddForce(Vector3 force, ForceMode mode = ForceMode.Force).

rb.AddForce(10.0f * Vector3.up);

if (Input.GetButtonDown("Jump") && _isGrounded)
{
  rb.AddForce(Vector3.up * Mathf.Sqrt(JumpHeight * -2f * Physics.gravity.y), ForceMode.VelocityChange);
}

Pentru a misca un caracter folosind inputul, de regula se foloseste functia MovePosition. Aceasta functie va incerca sa mute caracterul la pozitia respectiva, tinand cont de coliziuni. De asemenea, nu va influienta cu nimic procesarile fizice in desfasurare aplicate asupra RigidBody-ului, comenzile de miscare ale caracterului fiind separate oarecum de mecanica de simulare a interactiunilor fizice.

Vector3 dirVector = new Vector3 (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical")).normalized;
GetComponent <Rigidbody> ().MovePosition (transform.position + dirVector * Time.deltaTime);

Componenta Rigidbody este una foarte precisa din punct de vedere al coliziunilor, deci ofera mai mult control in acest sens, dar necesita si mai multa programare chiar si pentru lucruri simple, cum ar fi urcatul scarilor sau pe o rampa.

O mentiune importanta este ca Unity foloseste o separatie a procesarii functiilor de update in ceea ce priveste frame-ul. Astfel update-urile de procesare a fizicii sunt separate de update-urile de procesare a frame-ului:

  • exista o functie de FixedUpdate, care se apeleaza la un framerate fix si care se apeleaza inainte de fiecare `update de fizica`. In aceasta metoda este recomandat sa se aplice toate fortele necesare simularii fizice pentru a nu afecta simluarea facandu-o dependenta de framerate
  • functia clasica de Update, care duce la actualizarea si afisarea frame-ului curent: in aceasta functie se poate prelua inputul pentru a fi consistent

O problema generala care apare la preluarea inputului este normalizarea.

 Vector2 dirVector = new Vector2 (Input.GetAxis ("Horizontal"), Input.GetAxis ("Vertical"));

versus

 Vector2 dirVector = new Vector2 (Input.GetAxis ("Horizontal"), Input.GetAxis ("Vertical")).normalized;

Daca inputul nu este normalizat, caracterul se va misca cu o viteza mai mare atunci cand se misca in fi

Rotatia camerei

Pentru rotatia camerei exista mai multe variante, dar una dintre cele mai indiacate este sa retineti intotdeauna rotatia actuala a camerei, pentru a evita probleme legate de rotatii multiple compuse.

O varianta simpla:

    private float yaw = 0.0f;
    private float pitch = 0.0f;

    void Update () {
        yaw += speedH * Input.GetAxis("Mouse X");
        pitch -= speedV * Input.GetAxis("Mouse Y");

        transform.eulerAngles = new Vector3(pitch, yaw, 0.0f);
    }

Animatia personajelor

Animatia personajelor 3D, se face similar ca in 2D, fiind utilizata animatia bazata pe oase. Astfel, fiecare caracter 3D are definite oase (bones) care controleaza miscarea si animatia acestuia.

Crearea animatiilor se poate face folosind utilitarul de animatie (Window > Animation), similar ca in spatiul 2D. Similar, se poate folosi Animator Controller pentru a gestiona starile.

Ca notiune suplimentara, se pot defini stari de tranzitie/interpolare intre anumite animatii. Un exemplu comun este trecerea sau ajustarea animatiei de walk si run in functie de viteza curenta a personajului, sau a animatie de alergare stanga - fata - dreapta (daca sunt definite animatii diferite). Acest lucru se poate realiza folosind BlendTrees (Create State > From New Blend Tree).

Avatar Masks and Animation Layers

In cazul in care vrem sa combinam animatii putem folosi masti si niveluri de animatie.

Mastile ne permit sa facem discard la o portiune de animatie astfel incat sa preluam animatia doar pentru anumite parti de schelet.

Avatar Masks Masking allows you to discard some of the animation data within a clip, allowing the clip to animate only parts of the object or character rather than the entire thing. For example, if you had a character with a throwing animation. If you wanted to be able to use the throwing animation in conjunction with various other body movements such as running, crouching and jumping, you could create a mask for the throwing animation limiting it to just the right arm, upper body and head. This portion of the animation can then be played in a layer over the top of the base running or jumping animations.

In combinatie cu Layere de animatie in Unity putem combina diverse tipuri de animatii: de ex mers si tras in acelasi timp.

Animation Layers Unity uses Animation Layers for managing complex state machines for different body parts. An example of this is if you have a lower-body layer for walking-jumping, and an upper-body layer for throwing objects / shooting.

Wait for animation

Exista mai multe variante:

  • verificam starea animatiei
 Destroy (gameObject, this.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).length + delay); 
  • folosim corutine
  
  Update() {
  animation.Play("Die");
  waitForAnimation();
  }
  
  IEnumerator waitForAnimation() {
    yield WaitForSeconds (animation["CrouchRun"].length);
    
      Destroy(gameObject) ;
  
  dead = Instantiate( deadNew, dead.position, dead.transform.rotation);
  }
pjv/laboratoare/2023/05.txt ยท Last modified: 2024/10/07 10:48 by alexandru.gradinaru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0