Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pjv:laboratoare:2022:04 [2022/11/10 15:06]
alexandru.gradinaru
pjv:laboratoare:2022:04 [2022/11/23 13:12] (current)
alexandru.gradinaru
Line 9: Line 9:
   * Personaj (player)   * Personaj (player)
     * Controlabil     * Controlabil
-    ​* Are cel putin 2 atribute (de ex strength si dexterity) +    * Are viata (health) 
-    ​* Are viata (health) si viteza (speed) variabile in functie de atribute (de ex strength si dexterity+    * Are un XP care creste la diverse evenimente (de ex elimina un inamic, elimina un turn, rezolva un quest etc.)
-    * Are un XP care creste la diverse evenimente (de ex elimina un inamic, elimina un turn etc.)+
     * Poate interactiona cu obiecte (e un corp solid)     * Poate interactiona cu obiecte (e un corp solid)
     * Poate ataca inimicii     * Poate ataca inimicii
-  * Minim 3 obiecte ​de tip pick-up care pot creste atributele ​personajului ​- cate unul pentru fiecare atribut si viata+  * Minim 1 obiect ​de tip pick-up care pot reface viata personajului, implementat cu collider
-  * Inamici care se misca pe harta +  * Inamici care se misca pe harta (de ex patruleaza intr-o zona, sau se misca spre baza inamica) 
-    * In momentul in care detecteaza player-ul (intr-o anumita raza de exemplu) se intorc cu fata catre player si il urmaresc+    * In momentul in care detecteaza player-ul (intr-o anumita raza de exemplu) se intorc cu fata catre player si il urmaresc, implementat custom (fara collider)
     * Au viata (health)     * Au viata (health)
     * Pot muri - cand mor ofera experienta personajului     * Pot muri - cand mor ofera experienta personajului
-  ​Un minimap cu buline rosii pentru inamici si bulina albastra pentru player+ 
 +Bonus: 
 +  ​Quest system (fara interfata grafica)
  
 ==== Documentatie video ===== ==== Documentatie video =====
Line 66: Line 67:
 } }
 </​code>​ </​code>​
 +
 +La fel de bine aceste interactiuni pot fi detectate folosind sistemul de colizuni din Unity
 +> **Physics Events**
 +
 +<code c#>
 +/* 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) { }
 +
 +</​code>​
 +
  
 Astfel, toate obiectele ce vor avea interactiuni,​ vor mosteni aceasta clasa. Astfel, toate obiectele ce vor avea interactiuni,​ vor mosteni aceasta clasa.
Line 78: Line 104:
     //mecanica     //mecanica
     ...     ...
 +    PlayerManager.instance.score += value;
     ​     ​
     //distrugem obiectul     //distrugem obiectul
Line 98: Line 125:
 {{ :​pjv:​laboratoare:​gizmosselected.png?​direct&​750 |}} {{ :​pjv:​laboratoare:​gizmosselected.png?​direct&​750 |}}
  
 +=== Referinta globala la player ===
  
-O problema in activitatea agentilor ​este detectarea player-ului,​ in sensul de referinta. Astfel, avem mai multe variante: +O problema in programarea interactiunilor ​este detectarea player-ului,​ in sensul de referinta. Astfel, avem mai multe variante: 
-  * putem cauta un obiect dupa tag+  * putem cauta un obiect dupa tag/nume etc.
   * intr-o variabila target putem referentia direct player-ul (dar asta inseamna ca la fiecare agent trebuie mapat)   * intr-o variabila target putem referentia direct player-ul (dar asta inseamna ca la fiecare agent trebuie mapat)
   * putem folosi un singleton in care se tine referentiaza playerul si poate fi accesat de oriunde   * putem folosi un singleton in care se tine referentiaza playerul si poate fi accesat de oriunde
Line 118: Line 146:
 </​code>​ </​code>​
  
-Folosind varianta simpla cu singleton, putem lua pozitia player-ului de inters, similar cu laboratorul precedent:+Folosind varianta simpla cu singleton, putem lua pozitia player-ului de interes:
  
 <​code>​ <​code>​
Line 168: Line 196:
   * NPC-urile interactoneaza la fel, bazate pe o raza de actiune sau efectiv interactiune directa (click)   * NPC-urile interactoneaza la fel, bazate pe o raza de actiune sau efectiv interactiune directa (click)
  
 +Pentru ca un inamic sa se miste spre player, atunci cand player-ul intra in raza de actiune putem folosi componenta de NavMeshAgent
  
 +<​code>​
  
 +void Update() {
 +  //calculam distanta intre player si inamic
 +  float distance = Vector3.Distance(target.position,​ transform.position);​
 +
 +  if(distance <= radius)
 +  {
 +    //misca agentul pana la player
 +    agent.SetDestination(target.position);​
 +    ​
 +    //in momentul in care intra in raza de atac, ataca
 + 
 +  } else {
 +    // agentul se misca in treaba lui / patruleaza etc.
 +  }
 +</​code>​
 +  ​
 +Mai departe, se poate folosi o alta distanta, pentru a determina raza de atac. Un inamic poate avea atac melee (de aproape) sau de la o anumita distanta. ​
 +
 +<​code>​
 +
 +public float attackRadius = 1;
 +
 +void Update() {
 +  //calculam distanta intre player si inamic
 +  float distance = Vector3.Distance(target.position,​ transform.position);​
 +
 +  if(distance <= radius)
 +  {
 +    //misca agentul pana la player
 +    agent.SetDestination(hit.point);​
 +    ​
 +    //in momentul in care intra in raza de atac, ataca
 +    if(distance <= attack) ​
 +    {
 +      //ataca
 +    }
 + 
 +  }
 +  ​
 +</​code>​
 +
 +In multe cazuri avem actiuni mai complexe la mouse click dreapta: cum ar fi atacarea unui inamic, sau preluarea unui obiect etc, caz un care obiectele se pot misca in scena. Pentru asta, trebuie implementata o functie astfel incat sa se poata actualiza pozitia targetului curent.
 +
 +<​code>​
 +
 +Transform target = null;
 +
 +if(Input.GetMouseButtonDown(1)) //la apasarea click dreapta
 +{
 +  Ray mouseClickRay = camera.ScreenPointToRay(Input.mousePosition);​ //creaza o raza printr-un punct de pe ecran
 +  RaycastHit hit;
 +  ​
 +  if(Physics.Raycast(mouseClickRay,​ out hit))
 +  {
 +    target = hit.transform;​
 +    StartCoroutine(FollowTarget());​ //follow target pana la destinatie
 +  }
 +
 +}
 +
 +if(Input.GetMouseButtonDown(0)) //la apasarea click stanga
 +{
 +  target=null;​ //​dezactiveaza target-ul
 +}
 +
 +IEnumerator FollowTarget()
 +{
 +  while(target!=null) {
 +    agent.SetDestination(target); ​
 +    yield return null;
 +  }
 +  yield return 0;
 +}
 +</​code>​
  
 === Quest System === === Quest System ===
pjv/laboratoare/2022/04.1668085584.txt.gz · Last modified: 2022/11/10 15:06 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