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.
Desafio
Médio- Em
TowerData, adicione umsplashRadiuspúblico do tipo float: 0 significa sem dano em área. CannonData define o valor como 1.5. - Altere
Projectile.LaunchparaLaunch(Transform target, int damage, TowerData data)e mantenha os dados. EmTower, passe os dados da torre. - 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
blastPrefabserializado (um GameObject) no ponto de impacto, ajuste sua escala paraVector3.one * data.splashRadius * 2fe 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);
}
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.