Los Events (eventos) son unos delegates especializados
que son útiles para cuando usted quiere alertar
a otras clases que algo sucedió.
En práctica usted verá que los eventos
funcionan muy similar a los public multicast delegates.
Para más información acerca de delegates
ver la lección de delegates en el enlace abajo.
Un evento se puede pensar como un sistema de broadcast (difusión).
Cualquier clase que esté interesada en un evento
puede subscribir métodos a este.
Cuando esa situación específica ocurra,
como un click de un botón, o un power-up o una herida al jugador
nosotros invocamos nuestro evento y este de vuelta
llama los métodos de las clases suscritas.
Aquí nosotros tenemos una escena con 2 orbs.
Un orb tiene un script llamado TeleportScript
mientras que el otro tiene un script llamado TurnColorScript.
Adjuntado a nuestra cámara está el EventManagerScript.
Un evento se puede hacer para cualquier situación.
Pero en este ejemplo nosotros queremos invocar un evento
cuando el jugador haga click en un botón
que estamos dibujando a la pantalla.
En nuestro administrador de eventos (event manager) nosotros podemos ver
que hemos creado un tipo de delegate
que llamaremos ClickAction.
Podemos ver que cualquier método que desea estar subscrito
no debe tomar parámetros ni tener un tipo de retorno de void.
Luego nosotros creamos nuestra variable de evento.
Nosotros hacemos esto con la palabra clave Event.
Tenga en cuenta que esta variable también es estática
por la que podemos utilizar afuera de la clase
sin instanciar un objeto de esta clase.
Nuestra variable evento, que llamamos OnClicked
es el tipo de delegate que hemos creado arriba.
La única cosa es que la clase es responsable de
llamar el evento cuando la situación
apropiada suceda.
Como hemos mencionado antes,
nosotros llamaremos esto incluso cuando el jugador
haga click en un botón.
Por lo tanto, este script tiene un método OnGUI
Dentro del método OnGUI
nosotros hemos creado un botón en nuestra pantalla.
Cuando el jugador le hace click al botón
nosotros utilizamos una variable de evento como si fuera una función.
Esto en efecto invoca nuestro evento.
Por favor tenga en cuenta que como cualquier otro delegate
este causa un error si invocamos un evento
sin que tenga suscriptores.
Por lo tanto, siempre tenemos que asegurarnos
que el evento no sea igual a null
antes de invocarlo.
Si usted se acuerda de los 2 orbs en nuestra
escena, estos tienen 2 scripts diferentes adjuntos.
Estos 2 scripts van a funcionar como suscriptores
a este evento.
Miremos esto ahora.
En el TeleportScript nosotros hemos
creado un método llamado Teleport.
Este es el método al cual estaremos subscribiendo
al evento que hemos creado en el administrador de eventos (event manager).
Usted se dará cuenta que el método Teleport toma ningún parámetro
y tiene un tipo de retorno void,
como nuestro delegate.
El método Teleport es responsable del
posicionamiento del objeto de manera aleatoria a lo largo del eje Y.
Cerca de la parte superior de nuestro script
nosotros tenemos un método llamado OnEnable.
Este es un método integrado que será llamado
cuando el objeto que tiene este script
adjuntado es creado o habilitado en una escena.
Nosotros utilizaremos este método para subscribir nuestro
método Telport al evento OnClicked
del EventScript.
Podemos ver que subscribimos un método
a un evento utilizando el operador +=.
Al subscribir un método a un evento
nos estamos asegurando que cuando ese evento ocurra
nuestro método será llamado.
Luego nosotros tenemos un método OnDisable.
Opuesto al método OnEnable,
el método OnDisable es llamado cuando
un objeto es desactivado o destruido en una escena.
Dentro del método OnDisabled
nosotros estamos anulando la suscripción de nuestro método al evento.
Nosotros subscribimos un método de un evento
utilizando el operador -=.
Esto nos va asegurar que nuestro método no se
llame más cuando un evento ocurra.
Este paso es bastante importante
y el fallo de hacer esto puede llevar a pérdidas
de memoria y errores en nuestro juego.
Una buena regla es que cuando usted suscriba
un método a un evento usted debe
también cancelar una suscripción correspondientes.
Nuestro TurnColorScript
está estructurado muy similar a nuestro TeleportScript.
En este caso nosotros tenemos un método llamado TurnColor
que no toma parámetros y tiene un tipo
de retorno void.
El método TurnColor
vuelve el material del objeto en un color aleatorio.
Nuevamente, nosotros tenemos los métodos OnEnable
y OnDisable.
Esta vez, estos están suscribiendo
y anulando la suscripción de nuestro método TurnColor
del evento.
Vale la pena tener en cuenta en otro momento
que anulando la suscripción de nuestro método de un evento
es fundamental para utilizar eventos adecuadamente
y prevenir errores en nuestro código.
De vuelta en Unity nosotros podemos correr nuestra escena.
La primera cosa para tener en cuenta es el botón
que aparece cerca de la parte superior.
Cuando se haga click a este botón, se a invocará nuestro evento
y llamará los métodos Teleport y TurnColor.
Nosotros podemos hacer click en el botón múltiples veces
y cada vez los métodos suscriptores serán llamados.
Como podemos ver, nuestro administrador de eventos (event manager)
solamente necesita preocuparse acerca del evento en sí
y los factores desencadenantes al evento.
No necesitaba saber acerca del TeleportScript,
o el TurnColorScript.
Del mismo modo, el TeleportScript y TurnColorScript
no necesitaba saber acerca del otro.
De esta manera nosotros somos capaces de crear
un sistema de broadcast (difusión) muy robusto y flexible.
Usted se podría estar preguntando por qué utilizamos una variable
estática de evento en vez de una variable pública delegate
en nuestro administrador de eventos (event manager)?
La verdad es que usted puede lograr la misma
funcionalidad de eventos con variables públicas de delegates.
De hecho, como hemos mencionado al principio de esta lección,
los eventos son simplemente delegates especializados.
La razón por la cual nosotros utilizamos eventos sobre
variables públicas delegate para situaciones como esta
es que los eventos tienen una seguridad inherente
dónde las variables delegate no tienen.
Con eventos las otras clases
solamente se pueden suscribir y des-suscribir.
Si nosotros fuéramos a utilizar una variable pública delegate más bien
otras clases podrían invocar o
anular nuestra variable delegate para hacer
todo tipo de cosas nefastas.
En términos generales, si usted quiere crear un sistema de
métodos dinámicos que involucra más de 1 clase,
utilice variables de tipo evento más bien de variables delegate.