Menu
CoddyTech

Dano em área

Lição 14 de 18 do curso Jogo de Unity: Defesa de Torres da Coddy.

O projétil do Cannon explode onde cai e causa dano a todos os inimigos próximos à explosão, não apenas ao alvo. Physics.OverlapSphere(center, radius) retorna todos os colliders dentro de radius de center: inimigos, mas também o chão e o caminho. Cada collider que tem um IDamageable recebe o dano. O alvo é um deles, já que o projétil cai sobre ele, então não deve receber dano uma segunda vez por conta própria. Uma bomba que empurra todas as caixas ao redor:

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);
        }
    }
}

O raio da explosão é um dado do Cannon, então agora um projétil precisa de mais do que um valor de dano: Launch também recebe o TowerData da torre. O raio de explosão de uma Arrow é 0, então seus disparos continuam atingindo apenas o alvo. O dano continua sendo um argumento separado, já que depende do nível da torre.

Uma explosão mostra ao jogador onde o projétil caiu: uma esfera translúcida tão larga quanto o raio da explosão, que desaparece após um quarto de segundo. Destroy(blast, 0.25f) a destrói após esse atraso, sem precisar criar seu próprio temporizador.

challenge icon

Desafio

Médio
  1. Em TowerData, adicione um splashRadius público do tipo float: 0 significa sem dano em área. CannonData define o valor como 1.5.
  2. Altere Projectile.Launch para Launch(Transform target, int damage, TowerData data) e mantenha os dados. Em Tower, passe os dados da torre.
  3. Ao atingir o alvo, quando o raio de dano em área dos dados for maior que 0, todo collider dentro desse raio a partir do impacto que tiver um IDamageable recebe o dano, incluindo o alvo, uma única vez. Em seguida, mostre a explosão: instancie um blastPrefab serializado (um GameObject) no ponto de impacto, ajuste sua escala para Vector3.one * data.splashRadius * 2f e destrua-o após 0.25 segundos. Sem dano em área, somente o alvo recebe dano, como antes.

O prefab CannonBall tem o Blast em seu blastPrefab. Pressione Play, coloque um Cannon onde os inimigos se agrupam e, em seguida, Check.

Experimente você mesmo

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 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