This is an old revision of the document!


Programarea obiectelor

todo: raycast pentru selectia obiectelor - point and click mers la ele

Cerinte

Pentru simplitate puteti porni de la scena de MOBA creata in Lab3, dar nu este obligatoriu

Realizati o scena care sa contina:

  • Environment: teren cu copaci
  • Player
    • Controlabil
    • Are un healthbar afisat
    • Are cel putin 2 atribute (de ex strength si dexterity)
    • Are un inventar cu obiecte
      • accesibil pe tasta 'i'
      • obiectele se pot adauga, utiliza sau elimina din inventar
      • obiectele sunt de cel putin 2 tipuri:
        1. consumabil: de ex la apasarea pe el se poate recupera din viata personajului
        2. echipabil: de ex la o apasare se echipeaza - cresc anumite atribute ale playerului (strength, dexterity etc.) - la o alta apasare se dezechipeaza - scad atributele definite pe item
  • Inamici care se misca pe harta
    • Inamicii trebuie sa aiba healthbar deasupa capului
  • Un minimap cu buline rosii pentru inamici si bulina albastra pentru player

Documentatie video


Documentatie extinsa text


Sumar documentatie

Interactiunea cu obiectele

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();
      }
    }
  }

}

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

public class PickupObject : InteractionObject {

  public override void Interaction()
  {
    base.Interaction(); // se apeleaza metoda parinte, in caz ca avem ceva generic
    
    //mecanica
    ...
    
    //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);
}	

Quest System

In ceea ce priveste quest-urile, sunt foarte multe posibilitati de abordare, dar in general implica urmatoarele elemente:

  • obiectivele quest-ului
  • recompensele
  • cine gestioneaza quest-ul

Astfel, o abordare sugerata este sa se abstractizeze o clasa de tip Quest, una de tip Goal (obiectiv) si una de tip Recompensa, intrucat exista multe tipuri in care se pot instantia aceste lucruri.

Exemple de tipuri de Obiective:

  • Kill - kill a bunch of stuff
  • Gather - gather stuff for me
  • Deliver - deliver my live letter
  • etc.

Exemple de tipuri de Recompense:

  • items
  • experience
  • gold
  • skill
  • etc.

Exemplu de clasa generica de tip Quest

public class Quest : MonoBehaviour {

  public List<Goal> Goals = new List<Goal>();
  public List<Reward> Rewards = new List<Reward>();
  public bool completed;
  
  public void CheckGoals() {
    completed = Goals.All(g => g.completed); //questul este gata cand toate obiectivele sunt complete
  }
  
  public void GiveReward() {
    //in functie de tipul recompensei se adauga obiecte in inventar, sau se adauga experienta, skill points etc.
  }
  
  

}

Apoi, un exemplu de un quest concret.

public class RandomSlayThingsQuest : Quest {

  void Start()
  {
    QuestName = "Random Slayer";
    Description = "Kill some time";
    
    Goals.Add(new KillGoal( ...));
    Goals.Add(new KillGoal( ...));
    
    Rewards.Add(new ItemReward( ...));
    Rewards.Add(new ExperienceReward( ...));    
  
  }

}

Si un exemplu de Obiectiv

public class KillGoal : Goal {
  
  bool completed;
  int currentAmmount;
  
  public KillGoal(int enemyId, int ammount) {
    ...
  }
  
  public override void Init() {
    //listen to enemy death event
    EnemyManager.onDie += EnemyDied;
  }
  
  void EnemyDied(enemy) {
    this.currentAmmount++;
    if(this.currentAmmount >= ammount) {
      this.completed = true;
    }
  }
  
  
}

In ceea ce priveste cine gestioneaza questul, acesta este de obicei un NPC, deci putem extinde clasa NPC cu cateva lucuri specifice:

public class QuestNPC : NPC {
 

  public bool assigned;
  public Quest quest;
  
  public override void Interaction()
  {
    base.Interaction(); // se apeleaza metoda parinte

    if(!assigned) {
      //dialog
      //assign
    }
    
    void CheckQuest() {
      if(quest.completed) {
        quest.GiveReward();
      }
    }
  }
}

Inamici

Astfel, pentru inamici putem defini un controller cu un radius de actiune, si un gizmos pentru vizualizare usoara a acestuia in editor.

public class EnemyController : MonoBehaviour {

  public float radius = 2;
  
  void OnDrawGizmosSelected() {
    Gizmos.color = Color.red;
    Gizmos.DrawWireSphere(transform.position, radius);
  }


}

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