Llega a la base
Lección 3 de 18 del curso Juego de Unity: defensa de torres de Coddy.
Un enemigo que llega al último punto de ruta ha alcanzado la base: el jugador pierde vidas y el enemigo desaparece. Las vidas pertenecen a GameManager, que las muestra en pantalla. El enemigo no debería necesitar una referencia a GameManager para informarlo: pronto se crearán docenas de enemigos a partir de un prefab, y un prefab no puede apuntar a un objeto de la escena.
Un evento estático resuelve ambos problemas. Pertenece a la clase Enemy, no a un enemigo concreto, así que GameManager se suscribe una sola vez y recibe las notificaciones de todos los enemigos, también de los que aparezcan más adelante. Cada enemigo lo invoca pasándose a sí mismo como argumento, para que el receptor pueda leer qué tipo de enemigo logró pasar. Una moneda en un juego de plataformas informa de la misma manera:
public class Coin : MonoBehaviour
{
public static event Action<Coin> Collected;
public int value = 1;
void OnTriggerEnter(Collider other)
{
Collected?.Invoke(this);
Destroy(gameObject);
}
}// ScoreBoard.cs
void OnEnable()
{
Coin.Collected += AddCoin;
}
void OnDisable()
{
Coin.Collected -= AddCoin;
}
void AddCoin(Coin coin)
{
score += coin.value;
}Un evento estático vive tanto como el juego, así que -= importa más que nunca: se seguiría llamando a un ScoreBoard destruido que no se hubiera desuscrito, y su código fallaría al intentar acceder al texto destruido. OnEnable y OnDisable van en pareja, así que a cada += le corresponde su -=.
Desafío
FácilLa base necesita vidas, y cada enemigo que la alcance debe restarle vidas.
- En
EnemyData, agrega un int públicodamage: las vidas que este tipo le resta a la base. - En
Enemy, declara un evento estático públicoReachedBaseque pase el enemigo (Action<Enemy>). Cuando el enemigo llegue al último punto de ruta, invoca el evento pasándose a sí mismo y destruye al enemigo, en lugar de detenerse allí. - En
GameManager, agrega un int serializadostartLives(20) y un int privadolivesque comience con ese valor. Suscríbete aEnemy.ReachedBaseenOnEnabley cancela la suscripción enOnDisable. Cada enemigo que llegue resta de las vidas el valor dedamagede su recurso. - Muestra las vidas en un TMP_Text serializado
livesText, comoLives: 20, al inicio y después de cada cambio.
El objeto Game tiene el GameManager, en el Inspector se asigna LivesText, y ambos recursos restan 1 vida. Pulsa Play, espera a que ambos enemigos lleguen a la base y luego pulsa Check.
Pruébalo tú mismo
using UnityEngine;
public class Enemy : MonoBehaviour
{
public EnemyData data;
public Transform[] waypoints;
private int next = 1;
private int health;
void Awake()
{
health = data.maxHealth;
}
void Update()
{
if (next >= waypoints.Length)
{
return;
}
Vector3 target = waypoints[next].position;
transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
if (transform.position == target)
{
next++;
}
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.