Interactiuni cu obiecte

Cerinte

Implementati intr-o scena Unity urmatoarele obiecte de interactiune:

  • o zona invizibila care atunci cand esti in zona se afiseaza textul: “You are close!”
  • in mijlocul zonei un colectibil care ii va creste viata personajului
  • un turn care la atingere ii va scadea viata personajului si il va arunca putin inapoi (turnul nu poate fi distrus)

Trebuie sa aveti un personaj controlabil de la tastatura, care sa aiba un atribut de viata (nu neaparat afisat pe ecran).

Documentatie video

Inregistrare pe Teams

Documentatie extinsa text

Interactiunea cu obiectele in spatiul 3D poate fi extrem de complexa, intrucat exista foarte multe forme de interactiuni: inamici, obiecte de pickup, deschidere de usi, activare de manivele etc. Fiecare dintre aceste interactiuni are specificul ei, dar abstractizand, putem deduce ca fiecare interactiune se intampla intr-o anumita raza si cu un anumit punct de interactiune. Pentru a defini usor aceste lucruri, putem crea o clasa generica denumita InteractionObject cu o metoda abstracta (virtuala) ce defineste interactiunea in detaliu.

public class InteractionObject : MonoBehaviour {

  public float radius = 1f;
  public Transform interactionPoint;
  Transform interactionObject;
  bool done = false;

  //metoda abstracta, speficica fiecarui tip de interactiuni
  public virtual void Interaction ()
  {
		
  }

  void Update ()
  {
      float distance = Vector3.Distance(interactionObject.position, interactionPoint.position);

      if (distance <= radius && !done) // avem interactiune cu obiectul, pot sa afisez informatii: de ex "Press E to use"
      {
        done = true;
        Interaction();
      }
    }
  }

}

La fel de bine aceste interactiuni pot fi detectate folosind sistemul de colizuni din Unity

Physics Events
/* Both objects have to have a Collider and one object has to have a Rigidbody for these Events to work */
private void OnCollisionEnter(Collision hit) { Debug.Log(gameObject.name + " just hit " + hit.gameObject.name); }
private void OnCollisionStay(Collision hit) { Debug.Log(gameObject.name + " is hitting " + hit.gameObject.name); }
private void OnCollisionExit(Collision hit) { Debug.Log(gameObject.name + " stopped hitting " + hit.gameObject.name); }
 
/* Trigger must be checked on one of the Colliders */
private void OnTriggerEnter(Collider hit) { Debug.Log(gameObject.name + " just hit " + hit.name); }
private void OnTriggerStay(Collider hit) { Debug.Log(gameObject.name + " is hitting " + hit.name); }
private void OnTriggerExit(Collider hit) { Debug.Log(gameObject.name + " stopped hitting " + hit.name); }
 
/* For 2D Colliders just add 2D to the Method name and the Parameter Type */
private void OnCollisionEnter2D(Collision2D hit) { }
private void OnCollisionStay2D(Collision2D hit) { }
private void OnCollisionExit2D(Collision2D hit) { }
private void OnTriggerEnter2D(Collider2D hit) { }
private void OnTriggerStay2D(Collider2D hit) { }
private void OnTriggerExit2D(Collider2D hit) { }

OnCollision vs OnTrigger

OnCollisionEnter: este apelat atunci când coliderul sau corpul rigid al unui obiect de joc a început să atingă coliderul sau corpul rigid al unui alt obiect de joc.

În exemplul de mai jos, sfera și cubul au un colider implicit atașat pentru evenimentele de coliziune. Când sfera a intrat în coliziune cu cubul, OnCollisionEnter() este apelat și rulează codul pentru a schimba culorile pentru ambele obiecte.

Astfel, toate obiectele ce vor avea interactiuni, vor mosteni aceasta clasa. Spre exemplu pentru un obiect de pickup putem avea urmatoarea secventa:

OnTriggerEnter: este apelat atunci când un obiect de joc cu un colider trece printr-un obiect de joc cu colider bifat „Is Trigger”.

Obiectul cub are un colider implicit. Sfera are un colider de declanșare. Când sfera trece prin cub, OnTriggerEnter() este apelat și rulează codul pentru a schimba materialul sferei și a distruge cubul.

După cum putem vedea, există o diferență și utilizările sale.

Dacă vrem să creăm un joc despre mașini care se lovesc una împotriva celeilalte pentru distrugere, atunci am folosi un colider implicit cu „Is Trigger” nebifat și am apela OnCollisionEnter prin scripting. Când două mașini se ciocnesc, va apela OnCollisionEnter pe ambele obiecte de joc. Ciocnirile permit, de asemenea, fizica obiectului de joc.

Dacă vrem să colectăm obiecte sau poate să declanșăm o ușă sau un eveniment de cutscene, folosim un colider de verificare „Is Trigger” și apelăm OnTriggerEnter prin scripting. Când un jucător trece printr-un declanșator de coliziune cu trigger, poate începe un cutscene sau se deschide o ușă. Fizica este dezactivată pentru colizionare cu trigger.

Ambele sunt la fel de importante și utilizate pentru diferite mecanici într-un joc video.

public class PickupObject : InteractionObject {

  public override void Interaction()
  {
    base.Interaction(); // se apeleaza metoda parinte, in caz ca avem ceva generic
    
    //mecanica
    ...
    PlayerManager.instance.score += value;
    
    //distrugem obiectul
    Destroy(gameObject);
    
  }
}

Pentru a controla mai bine zona de actiune (radius) si punctul de interes pentru un obiect de interactiune (InteractionObject), se poate defini o functie de editor, atunci cand obiectul este selectat. In exemplul de mai jos, la selectarea obiectului se va afisa o sfera wireframe de culoare alba.

void OnDrawGizmosSelected ()
{
  Gizmos.color = Color.white;
  Gizmos.DrawWireSphere(interactionPoint.position, radius);
}	

pjv/laboratoare/2023/06.txt · Last modified: 2023/11/20 15:50 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