Differences

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

Link to this comparison view

pjv:laboratoare:2022:04 [2022/11/10 14:01]
alexandru.gradinaru
pjv:laboratoare:2022:04 [2022/11/23 13:12] (current)
alexandru.gradinaru
Line 1: Line 1:
 ===== Programarea obiectelor ===== ===== Programarea obiectelor =====
- 
-todo: raycast pentru selectia obiectelor - point and click mers la ele 
- 
  
 ==== Cerinte ===== ==== Cerinte =====
  
-<note important>​Pentru simplitate puteti porni de la scena de MOBA creata in Lab3, dar nu este obligatoriu</​note>​+<note important>​Pentru simplitateputeti porni de la scena de MOBA creata in Lab3, dar nu este obligatoriu</​note>​
  
 Realizati o scena care sa contina: Realizati o scena care sa contina:
  
-  * Environment:​ teren cu copaci +  * Personaj (player)
-  * Player+
     * Controlabil     * Controlabil
-    * Are un healthbar afisat +    * Are viata (health) 
-    * Are cel putin 2 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 inventar ​cu obiecte +    * Poate interactiona ​cu obiecte ​(e un corp solid) 
-      accesibil pe tasta '​i'​ +    Poate ataca inimicii 
-      * obiectele se pot adauga, utiliza sau elimina din inventar +  Minim 1 obiect ​de tip pick-up care pot reface ​viata personajului, implementat cu collider. 
-      ​obiectele sunt de cel putin 2 tipuri:  +  * Inamici care se misca pe harta (de ex patruleaza intr-zona, sau se misca spre baza inamica) 
-        ​consumabil: de ex la apasarea pe el se poate recupera din viata personajului +    * 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) 
-        - echipabil: ​de ex la apasare ​se echipeaza ​cresc anumite atribute ale playerului ​(strength, dexterity etc.) la alta apasare ​se dezechipeaza - scad atributele definite pe item +    Au viata (health) 
-  Inamici care se misca pe harta +    * Pot muri - cand mor ofera experienta personajului 
-    * Inamicii trebuie sa aiba healthbar deasupa capului + 
-  * Un minimap cu buline rosii pentru inamici si bulina albastra pentru player+Bonus: 
 +  * Quest system (fara interfata grafica)
  
 ==== Documentatie video ===== ==== Documentatie video =====
Line 37: Line 34:
 ==== Sumar documentatie ===== ==== Sumar documentatie =====
  
 +todo: raycast pentru selectia obiectelor - point and click mers la ele
 ==== Interactiunea cu obiectele ==== ==== Interactiunea cu obiectele ====
  
Line 70: 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 82: Line 104:
     //mecanica     //mecanica
     ...     ...
 +    PlayerManager.instance.score += value;
     ​     ​
     //distrugem obiectul     //distrugem obiectul
Line 102: Line 125:
 {{ :​pjv:​laboratoare:​gizmosselected.png?​direct&​750 |}} {{ :​pjv:​laboratoare:​gizmosselected.png?​direct&​750 |}}
  
 +=== Referinta globala la player ===
  
 +O problema in programarea interactiunilor este detectarea player-ului,​ in sensul de referinta. Astfel, avem mai multe variante:
 +  * 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)
 +  * putem folosi un singleton in care se tine referentiaza playerul si poate fi accesat de oriunde
 +
 +<​code>​
 +public class PlayerManager : MonoBehaviour {
 + 
 +  public static PlayerManager instance;
 +  public GameObject player;
 +    ​
 +  void Awake()
 +  {
 +    instance = this;
 +  }
 +
 +}
 +</​code>​
 +
 +Folosind varianta simpla cu singleton, putem lua pozitia player-ului de interes:
 +
 +<​code>​
 +target = PlayerManager.instance.player.transform;​
 +</​code>​
 +
 +Astfel, putem efectua usor operatii care tin de player - de exemplu putem orienta inamicii sau un npc cu fata catre player, in momentul unei interactiuni.
 +
 +<​code>​
 +
 +        //Roteste cu 90 grade
 +        void RotateN() {
 +         ​Vector3 currentRotation = transform.rotation;​
 +         ​Vector3 wantedRotation = currentRotation * Quaternion.AngleAxis(-90,​ Vector3.up);​
 +         ​transform.rotation = Quaternion.Slerp(currentRotation,​ wantedRotation,​ Time.deltaTime * rotationSpeed);​
 +        }
 +        //Roteste inamicul cu fata catre player ​
 + void FaceTarget ()
 + {
 + Vector3 direction = (target.position - transform.position).normalized;​
 + Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x,​ 0, direction.z));​
 + transform.rotation = Quaternion.Slerp(transform.rotation,​ lookRotation,​ Time.deltaTime * 5f);
 + }
 +</​code>​
 +
 +
 +
 +=== Inamici ===
 +
 +Astfel, pentru inamici putem defini un controller cu un radius de actiune, si un gizmos pentru vizualizare usoara a acestuia in editor.
 +
 +<​code>​
 +public class EnemyController : MonoBehaviour {
 +
 +  public float radius = 2;
 +  ​
 +  void OnDrawGizmosSelected() {
 +    Gizmos.color = Color.red;
 +    Gizmos.DrawWireSphere(transform.position,​ radius);
 +  }
 +
 +
 +}
 +</​code>​
 +
 +{{ :​pjv:​laboratoare:​enemy-radius.png?​500 |}}
 +Diferenta este ca acesti agenti vor raspunde automat la anumite evenimente:
 +  * inamicii de obicei incep sa interactioneze atunci cand player-ul intra intr-o anumita raza de actiune
 +  * 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 ===
Line 229: Line 400:
  
 </​code>​ </​code>​
- 
- 
-=== Inamici === 
- 
-Astfel, pentru inamici putem defini un controller cu un radius de actiune, si un gizmos pentru vizualizare usoara a acestuia in editor. 
- 
-<​code>​ 
-public class EnemyController : MonoBehaviour { 
- 
-  public float radius = 2; 
-  ​ 
-  void OnDrawGizmosSelected() { 
-    Gizmos.color = Color.red; 
-    Gizmos.DrawWireSphere(transform.position,​ radius); 
-  } 
- 
- 
-} 
-</​code>​ 
- 
-{{ :​pjv:​laboratoare:​enemy-radius.png?​500 |}} 
-Diferenta este ca acesti agenti vor raspunde automat la anumite evenimente: 
-  * inamicii de obicei incep sa interactioneze atunci cand player-ul intra intr-o anumita raza de actiune 
-  * NPC-urile interactoneaza la fel, bazate pe o raza de actiune sau efectiv interactiune directa (click) 
- 
- 
  
  
  
pjv/laboratoare/2022/04.1668081662.txt.gz · Last modified: 2022/11/10 14:01 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