Recompensas
Lição 13 de 25 do curso Jogo de Unity: Defesa de Torres da Coddy.
Cada inimigo que uma torre derruba paga sua reward. O Enemy informa a eliminação da mesma forma que informa que chegou à base, com um evento estático, Killed, e o GameManager escuta e adiciona o dinheiro.
Uma eliminação deve ser paga uma única vez. Destroy não remove um objeto imediatamente: isso acontece no fim do frame e, até lá, ele ainda está no jogo. Dois disparos podem acertar no mesmo frame, e o segundo encontra um inimigo com 0 de vida que ainda está lá. Se TakeDamage informar uma eliminação toda vez que a vida estiver em 0 ou menos, o segundo disparo paga de novo. Um jogo de estourar balões com dardos tem a mesma armadilha, e um bool resolve isso:
public void Pop()
{
if (popped)
{
return;
}
popped = true;
Popped?.Invoke(this);
Destroy(gameObject);
}O inimigo não precisa de um bool extra, já que sua vida indica se ele está morto: um TakeDamage que encontra a vida em 0 ou menos não tem mais nada a fazer.
Desafio
MédioCada inimigo derrotado rende a recompensa correspondente.
- Em
Enemy, adicionepublic static event Action<Enemy> Killed;e invoque o evento emTakeDamagelogo antes de destruir o inimigo. - Comece
TakeDamagecomif (health <= 0) return;, para que uma eliminação seja recompensada apenas uma vez. - Em
GameManager, adicionepublic void Earn(int amount)(adicione o valor e mostre-o) e inscreva-se emEnemy.Killedpara receberenemy.data.reward.
Pressione “Jogar”: o dinheiro aumenta enquanto as torres trabalham. Em seguida, pressione “Verificar”.
Experimente você mesmo
using System;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour, IDamageable
{
public static readonly List<Enemy> All = new List<Enemy>();
public static event Action<Enemy> ReachedBase;
public EnemyData data;
public Transform[] waypoints;
private int next = 1;
private int health;
void Awake()
{
health = data.maxHealth;
}
void OnEnable()
{
All.Add(this);
}
void OnDisable()
{
All.Remove(this);
}
void Update()
{
Vector3 target = waypoints[next].position;
transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
if (transform.position == target)
{
next++;
if (next == waypoints.Length)
{
ReachedBase?.Invoke(this);
Destroy(gameObject);
}
}
}
public void TakeDamage(int amount)
{
health -= amount;
if (health <= 0)
{
Destroy(gameObject);
}
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Jogo de Unity: Defesa de Torres
Pratique por conta própria: Playground de Unity