Menu
CoddyTech

Recompensas

Lição 10 de 18 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.

challenge icon

Desafio

Médio
  1. Em Enemy, declare um evento estático público Killed (Action<Enemy>). Dispare-o com o inimigo quando TakeDamage reduzir a vida dele a 0 ou menos, imediatamente antes de destruí-lo.
  2. Uma eliminação paga uma vez: quando TakeDamage é chamado em um inimigo cuja vida já está em 0 ou menos, ele não faz nada.
  3. Em GameManager, adicione public void Earn(int amount), que adiciona dinheiro e o exibe. Inscreva-se em Enemy.Killed junto com ReachedBase e receba a reward do inimigo eliminado.

Pressione Play e observe o dinheiro aumentar enquanto as torres trabalham; em seguida, clique em Check.

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);
        }
    }
}
quiz iconTeste seus conhecimentos

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