Menu
CoddyTech

Recompensas

Lección 10 de 18 del curso Juego de Unity: defensa de torres de Coddy.

Cada enemigo que una torre derriba paga su reward. Enemy informa de la eliminación igual que informa de que ha llegado a la base, mediante un evento estático, Killed, y GameManager lo escucha y añade el dinero.

Una eliminación debe pagarse una sola vez. Destroy no elimina un objeto de inmediato: lo hace al final del fotograma, y hasta entonces sigue en el juego. Dos disparos pueden impactar en el mismo fotograma, y el segundo encuentra a un enemigo con 0 de salud que todavía sigue ahí. Si TakeDamage informa de una eliminación cada vez que la salud está en 0 o menos, ese segundo disparo vuelve a pagar. Un juego de globos con dardos tiene la misma trampa, y un bool la evita:

public void Pop()
{
    if (popped)
    {
        return;
    }

    popped = true;
    Popped?.Invoke(this);
    Destroy(gameObject);
}

El enemigo no necesita ningún bool adicional, ya que su salud ya indica si está muerto: un TakeDamage que encuentra la salud en 0 o menos no tiene nada más que hacer.

challenge icon

Desafío

Intermedio
  1. En Enemy, declara un evento estático público Killed (Action<Enemy>). Actívalo con el enemigo cuando TakeDamage reduzca su salud a 0 o menos, justo antes de destruirlo.
  2. Una eliminación se recompensa una sola vez: cuando se llama a TakeDamage en un enemigo cuya salud ya está en 0 o menos, no hace nada.
  3. En GameManager, añade public void Earn(int amount), que suma dinero y lo muestra. Suscríbete a Enemy.Killed junto a ReachedBase y gana la reward del enemigo eliminado.

Pulsa Jugar y observa cómo aumenta el dinero mientras trabajan las torres; después, pulsa Comprobar.

Pruébalo tú mismo

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 iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Juego de Unity: defensa de torres