Hola 😄
Con estos retos me sentí creativo y me puse a hacer las cosas de una forma un tanto diferente a lo venimos haciendo en el curso. No se como vaya a resultar a futuro conforme vaya creciendo el proyecto, pero es parte de la diversión 😜
Destruir el enemigo
Al principio solo agregue, dentro del script de Enemy, una condición de que se destruyera el gameObject cuando health fuese menor o igual a 0
Pero me sentí inspirado y decidí extraer el comportamiento de ser "dañable" a otro script, para poder reutilizarlo luego con el Player u otros objetos
Para este comportamiento "Damageable" se me ocurrió que iba a querer que pudieran suceder diferentes cosas al gameObject cuando se quedara sin vida, así que le agregué creé un event llamado OnEmptyHealt que me sirviera para ejecutar N cantidad de comportamientos cuando el gameObject en cuestión se quedase sin vida
Esto tiene que ver con Delegados y Eventos
Una explicación algo burda del código de arriba (que bien puede que no sea del todo correcta, pero me ayuda a entenderle un poco) sería
En la línea 6 digo:
He aquí un tipo de delegado, que recibe cero parámetros y no retorna ningún valor, este tipo de delegado se llama EmptyHealthAction
En la línea 7 digo:
He aquí un evento cuyo nombre es OnEmptyHealth, que puede ejecutar delegados del tipo EmptyHealthAction
y en las líneas 11 y 12 digo:
si la vida es menor o igual a cero y el evento OnEmptyHealt tiene algún delegado a ejecutar, invoca al evento OnEmptyHealth para que ejecute todas los delegados que tiene asignados
Ya con eso listo, en el OnTriggerEnter2D de Bullet cambié el componente se obtiene de Enemy a Damageable
Ahora lo que me faltaba era crear scripts/comportamientos independientes que pudiera escuchar al evento OnEmptyHealth del Damageable
Para esto creé una clase abstracta, llamada DieBehaviour, que tuviera la lógica de:
- Requerir que el game object en el que se encuentra el script tenga el componente Damageable (DieBehaviour linea 3)
- Obtener el componente Damageable para poder suscribirme al evento OnEmptyHealth mas adelante (DieBehaviour línea 9)
- Suscribir y des suscribirse al evento cuando el script o el gameObject en el que esté sea habilitado o deshabilitado (DieBehaviour línea 11 a 18)
- Y declarar un método abstracto Die, para que quien implemente la clase lo sobre escriba
Y ya con esa clase abstracta como plano, cree el script "DestroyOnDeath" que destruye al gameObject cuando muere, aquí está el código
La idea de esto es que ahora que quiera crear una lógica especial para cuando un GameObject que sea Damageable "muera" basta con crear un script que herede la clase DieBehaviour, agregarle la lógica que quiera en el método Die y ya
Ahora puedo agregar y mezclando diferentes o/y multiples comportamientos a la muerte de un GameObject simplemente arrastrando los scripts que vaya creando.
Por ejemplo si tuviera el siguiente catalogo de efectos que puedan suceder cuando un Damageable muera, separado cada uno en su propio script
- invocar n cantidad de enemigos al morir,
- darle un efecto de ceguera al jugador al morir
- explotar al morir
- marcar el juego como terminado al morir (si muere el jugador por ejemplo)
- re-vivir a la entidad en otro lugar
- darle un efecto positivo al que lo mató
- lanzar una onda congeladora alrededor de donde muere
Podría combinarlos en diferentes enemigos y tener un enemigo que al morir explote y te de un efecto de ceguera, o uno que lance una onda congeladora al rededor y después invoque a otros 3 enemigos cuando muera.
Al final el prefab de mi Enemy quedó así por ahora:
Dañar al jugador cuando los enemigos lo toquen
Para dañar al jugador le agregué
- un Riggidbody 2D, con gravedad 0
- y un CircleCollider2D
Le agregué el evento OnTriggerEnter2D al script de Player para que cuando chocara con un enemigo se haga daño
Creé un script para que se escriba el nombre del GameObject cuando muere, para ver que el player pueda morir
y al GameObject Player le puse los componentes "Damageable" y "Print Message On Death"
Así quedó el player