Comunidad orientada al desarrollo de videojuegos

Unity3D – Eventos

Bueno, pasemos a un pequeño post de programación. En Unity3D usamos eventos en todo momento: Awake, Update, OnCollisionEnter, etc. pero no solemos salir de los eventos que nos proporciona Unity3D. Gracias a C# podemos definir nuestros propios eventos.

 

Un evento, básicamente, es la forma que tiene una clase de comunicar a uno o varios objetos cuando ocurre algo. Cualquier objeto se podrá subscribir al evento sin ninguna necesidad de que nuestro evento tenga conocimiento de sus subscriptores.

 

Para declarar un evento, primero debemos declarar un tipo delegado para el evento. El delegado, define los argumentos que se le pasarán al método que manejará el evento.

   1: public delegate void MyEventHandler();

   2: public delegate void EventHandler (GameObject e);

   3: public delegate void CollisionHandler (GameObject e, Collision c);

 

Pongamos un supuesto, en el que queramos lanzar un evento cuando la vida de nuestro personaje ha llegado a cero. De esta forma, podemos crearnos los objetos que creamos necesarios y subscribirnos a este evento, por ejemplo, si queremos notificar la muerte del personaje, si hay una poción activa que te rellena la vida cuando esta llega a cero, si queremos acabar el nivel y volver al menú principal, etc.

   1: public class EventDispatcher : MonoBehaviour {

   2:  

   3:     public event MyEventHandler OnDead;

   4:     public delegate void MyEventHandler ();

   5:  

   6:     private int vida = 100;

   7:     

   8:     void Update ()

   9:     {

  10:         vida--;

  11:         if(vida < 0)

  12:         {

  13:             if (OnDead != null)

  14:                 OnDead();

  15:         }

  16:     }

  17: }

 

Si analizamos el código de arriba, vemos que declaramos un evento del tipo MyEventHandler llamado OnDead y un delegado que no devuelve nada y que no tiene argumentos para el tipo MyEventHandler. De esta forma, cuando la vida de nuestro personaje llega a cero, lanzamos el evento OnDead.

 

Ahora que ya estamos exponiendo nuestro evento, vamos a ver como podemos subscribirnos a él.

   1: public class DeadController : MonoBehaviour

   2: {

   3:  

   4:     public GameObject player;

   5:  

   6:     void Start ()

   7:     {

   8:         player.GetComponent<EventDispatcher>().OnDead += DeadController_OnDead;

   9:     }

  10:  

  11:     void DeadController_OnDead()

  12:     {

  13:         Debug.Log("Dead!");

  14:         player.GetComponent<EventDispatcher>().OnDead -= DeadController_OnDead;

  15:     }

  16: }

 

En el código anterior, vamos a subscribirnos al evento OnDead de la clase EvenHandler y para ello, hemos declarado un GameObject público, que será la referencia a nuestro GameObject que lanzará el evento. Obtenemos el componente EventDispatcher y con el operador += nos subscribimos mediante el método DeadController_OnDead, de esta forma, en cuando se lance el evento, se ejecutará el código que haya dentro del método DeadController_OnDead. Fijaros también en el operado –= que hay dentro del método, de esta forma eliminamos la subscripción al evento, puesto que ya hemos ejecutado el código que queríamos, si no se volvería a ejecutar.

 

Si os fijáis, nos podemos ahorrar el evento Update (para preguntar en cada pasada por la vida de nuestro personaje) de los objetos subscriptores a este evento. Esto debería influir en el rendimiento favorablemente.

 

También podemos declararnos eventos que se lancen cuando un evento genérico se ejecuta, de esta forma, podríamos crearnos una clase genérica de notificaciones de eventos para cualquier GameObject, un ejemplo con un par de eventos sería el siguiente:

   1: public class EventDispatcher : MonoBehaviour

   2: {

   3:     public delegate void EventHandler(GameObject e);

   4:     public delegate void CollisionHandler(GameObject e, Collision c);

   5:  

   6:     public event EventHandler MouseOver;

   7:     void OnMouseOver()

   8:     {

   9:         if (MouseOver != null)

  10:             MouseOver(this.gameObject);

  11:     }

  12:    

  13:     public event CollisionHandler CollisionEnter;

  14:     void OnCollisionEnter(Collision c)

  15:     {

  16:         if (CollisionEnter != null)

  17:             CollisionEnter(this.gameObject, c);

  18:     }

  19: }

 

Saludos!

, , , ,

2 thoughts on “Unity3D – Eventos

Leave a Reply