Menu
CoddyTech

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.

challenge icon

Desafio

Médio

Cada inimigo derrotado rende a recompensa correspondente.

  1. Em Enemy, adicione public static event Action<Enemy> Killed; e invoque o evento em TakeDamage logo antes de destruir o inimigo.
  2. Comece TakeDamage com if (health <= 0) return;, para que uma eliminação seja recompensada apenas uma vez.
  3. Em GameManager, adicione public void Earn(int amount) (adicione o valor e mostre-o) e inscreva-se em Enemy.Killed para receber enemy.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);
        }
    }
}
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

Pratique por conta própria: Playground de Unity