Splash
Lesson 20 of 25 in Coddy's Unity Game: Tower Defense course.
The Cannon's shell bursts where it lands and hurts every enemy near the blast, not only its target. Physics.OverlapSphere(center, radius) returns every collider within radius of center: enemies, but also the ground and the path. Each collider that has an IDamageable takes the damage. The target is one of them, since the shell lands on it, so it must not be hurt a second time on its own. A bomb that knocks back every crate around it:
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);
}
}
}The splash radius is the Cannon's data, so a projectile now needs more than a damage number: Launch takes the tower's TowerData too. An Arrow's splash radius is 0, so its shots keep hitting their target alone. The damage stays a separate argument, since it depends on the tower's level.
A blast shows the player where the shell burst: a see-through sphere as wide as the splash, gone after a quarter of a second. Destroy(blast, 0.25f) destroys it after that delay, with no timer of your own.
Challenge
MediumCannon shells burst and hurt every enemy nearby.
- In
TowerData, addpublic float splashRadius;(CannonData sets 1.5).Launchtakes a third argument,TowerData data, which the Tower passes. - On arrival, with
data.splashRadius > 0, each IDamageable inPhysics.OverlapSphere(transform.position, data.splashRadius)takes the damage once; else only the target. - Then show a serialized
blastPrefabthere, scaledVector3.one * data.splashRadius * 2f, andDestroy(blast, 0.25f).
Press Play: a Cannon blast hurts bunched Grunts. Then Check.
Try it yourself
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);
}
}
}
All lessons in Unity Game: Tower Defense
Practice on your own: Unity playground