Menu
CoddyTech

Recompensas

Lección 13 de 25 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

Cada enemigo eliminado paga su recompensa.

  1. En Enemy, añade public static event Action<Enemy> Killed; y actívalo en TakeDamage justo antes de destruir al enemigo.
  2. Empieza TakeDamage con if (health <= 0) return;, para que la eliminación se pague una sola vez.
  3. En GameManager, añade public void Earn(int amount) (añádelo y muéstralo) y suscríbete a Enemy.Killed para obtener enemy.data.reward.

Pulsa «Jugar»: el dinero aumenta mientras las torres trabajan. 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

Practica por tu cuenta: Playground de Unity