Menu
CoddyTech

Daño de área

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

El proyectil del Cañón estalla donde aterriza y daña a todos los enemigos cercanos a la explosión, no solo a su objetivo. Physics.OverlapSphere(center, radius) devuelve todos los colisionadores que están a una distancia de radius de center: enemigos, pero también el suelo y el camino. Cada colisionador que tenga un IDamageable recibe el daño. El objetivo es uno de ellos, ya que el proyectil aterriza sobre él, así que no debe recibir daño por segunda vez por su cuenta. Una bomba que empuja hacia atrás todas las cajas cercanas:

void Explode()
{
    foreach (Collider other in Physics.OverlapSphere(transform.position, blastRadius))
    {
        if (other.TryGetComponent(out Rigidbody body))
        {
            Vector3 away = (body.position - transform.position).normalized;
            body.AddForce(away * push, ForceMode.Impulse);
        }
    }
}

El radio de explosión es un dato del Cañón, así que ahora un proyectil necesita más que un número de daño: Launch también recibe el TowerData de la torre. El radio de explosión de una Flecha es 0, así que sus disparos siguen impactando solo a su objetivo. El daño sigue siendo un argumento independiente, ya que depende del nivel de la torre.

Una explosión le muestra al jugador dónde estalló el proyectil: una esfera transparente tan amplia como el radio de explosión, que desaparece al cabo de un cuarto de segundo. Destroy(blast, 0.25f) la destruye después de esa demora, sin necesidad de que crees tu propio temporizador.

challenge icon

Desafío

Intermedio
  1. En TowerData, añade un float público splashRadius: 0 significa que no hay daño de área. CannonData establece 1.5.
  2. Cambia Projectile.Launch a Launch(Transform target, int damage, TowerData data) y conserva los datos. En Tower, pasa los datos de la torre.
  3. Al llegar, cuando el radio de daño de área de los datos sea mayor que 0, todos los colisionadores dentro de ese radio desde el punto de impacto que tengan un IDamageable reciben el daño, incluido el objetivo, una sola vez. Después, muestra la explosión: instancia un blastPrefab serializado (un GameObject) en el punto de impacto, escálalo a Vector3.one * data.splashRadius * 2f y destrúyelo después de 0.25 segundos. Sin daño de área, solo recibe daño el objetivo, como antes.

El prefab CannonBall tiene la explosión en su blastPrefab. Pulsa Play, coloca un Cannon donde se agrupen los enemigos y, después, pulsa Check.

Pruébalo tú mismo

using UnityEngine;

public class Projectile : MonoBehaviour
{
    [SerializeField] private float speed = 12f;

    private Transform target;
    private int damage;

    public void Launch(Transform target, int damage)
    {
        this.target = target;
        this.damage = damage;
    }

    void Update()
    {
        if (target == null)
        {
            Destroy(gameObject);
            return;
        }

        transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
        if (transform.position == target.position)
        {
            if (target.TryGetComponent(out IDamageable damageable))
            {
                damageable.TakeDamage(damage);
            }
            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