Chegue à base
Lição 3 de 18 do curso Jogo de Unity: Defesa de Torres da Coddy.
Um inimigo que chega ao último ponto de passagem alcançou a base: o jogador perde vidas e o inimigo desaparece. As vidas pertencem ao GameManager, que as exibe na tela. O inimigo não deveria precisar de uma referência ao GameManager para informar isso: em breve, os inimigos serão criados às dúzias a partir de um prefab, e um prefab não pode apontar para um objeto na cena.
Um evento estático resolve os dois problemas. Ele pertence à classe Enemy, não a um único inimigo, então o GameManager se inscreve uma vez e recebe notificações de todos os inimigos, inclusive dos que forem instanciados mais tarde. Cada inimigo o aciona passando a si mesmo como argumento, para que o ouvinte possa ler que tipo de inimigo conseguiu passar. Uma moeda em um jogo de plataforma informa da mesma maneira:
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;
}Um evento estático existe enquanto o jogo estiver em execução, então o -= é mais importante do que nunca: um ScoreBoard destruído que nunca se desinscreveu ainda seria chamado, e seu código falharia ao acessar o texto destruído. OnEnable e OnDisable vêm em pares, então cada += recebe seu -=.
Desafio
FácilA base precisa de vidas, e um inimigo que a alcance deve fazer com que elas diminuam.
- Em
EnemyData, adicione umpublic intdamage: a quantidade de vidas que esse tipo de inimigo tira da base. - Em
Enemy, declare um evento estático públicoReachedBaseque passe o inimigo (Action<Enemy>). Quando o inimigo chegar ao último waypoint, dispare o evento passando o próprio inimigo e destrua-o, em vez de fazê-lo parar ali. - Em
GameManager, adicione umintserializadostartLives(20) e umintprivadolivesque comece com esse valor. Inscreva-se emEnemy.ReachedBaseemOnEnablee cancele a inscrição emOnDisable. Cada inimigo que passar reduz das vidas o valor dedamagedo asset dele. - Mostre as vidas em um
TMP_TextserializadolivesText, comoLives: 20, no início e após cada alteração.
O objeto Game tem o GameManager, o Inspector vincula o LivesText, e ambos os assets tiram 1 vida. Pressione Play, espere os dois inimigos chegarem à base e, em seguida, Check.
Experimente você mesmo
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 lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.