Menu
CoddyTech

Splash

Lesson 14 of 18 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 icon

Challenge

Medium
  1. In TowerData, add a public float splashRadius: 0 means no splash. CannonData sets 1.5.
  2. Change Projectile.Launch to Launch(Transform target, int damage, TowerData data) and keep the data. In Tower, pass the tower's data.
  3. On arrival, when the data's splash radius is above 0, every collider within that radius of the impact that has an IDamageable takes the damage, the target included, once. Then show the blast: instantiate a serialized blastPrefab (a GameObject) at the impact, scale it to Vector3.one * data.splashRadius * 2f and destroy it after 0.25 seconds. With no splash, only the target is hurt, as before.

The CannonBall prefab has the Blast in its blastPrefab. Press Play, put a Cannon where the enemies bunch up, 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);
        }
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Unity Game: Tower Defense