This is an old revision of the document!


Programarea obiectelor

Cerinte

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();
      }
    }
  }
}
pjv/laboratoare/2022/05.1667987180.txt.gz ยท Last modified: 2022/11/09 11:46 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