Menu
CoddyTech

Dégâts de zone

Leçon 14 sur 18 du cours Jeu Unity : défense de tours de Coddy.

L’obus du Canon explose à l’endroit où il atterrit et blesse tous les ennemis proches de l’explosion, pas seulement sa cible. Physics.OverlapSphere(center, radius) renvoie chaque collider situé à moins de radius de center : les ennemis, mais aussi le sol et le chemin. Chaque collider qui possède un IDamageable subit les dégâts. La cible en fait partie, puisque l’obus atterrit dessus ; elle ne doit donc pas être touchée une deuxième fois par son propre obus. Une bombe qui repousse toutes les caisses autour d’elle :

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

Le rayon d’explosion est une donnée du Canon ; un projectile a donc désormais besoin de plus qu’une valeur de dégâts : Launch prend également le TowerData de la tour. Le rayon d’explosion d’une flèche est de 0, ses tirs continuent donc de toucher uniquement leur cible. Les dégâts restent un argument distinct, car ils dépendent du niveau de la tour.

Une explosion montre au joueur où l’obus a éclaté : une sphère transparente aussi large que le rayon d’explosion, qui disparaît au bout d’un quart de seconde. Destroy(blast, 0.25f) la détruit après ce délai, sans que tu aies à gérer ton propre minuteur.

challenge icon

Défi

Moyen
  1. Dans TowerData, ajoutez un float public splashRadius : 0 signifie qu’il n’y a pas d’explosion. CannonData définit la valeur à 1.5.
  2. Modifiez Projectile.Launch en Launch(Transform target, int damage, TowerData data) et conservez les données. Dans Tower, transmettez les données de la tour.
  3. À l’arrivée, lorsque le rayon d’explosion des données est supérieur à 0, chaque collider situé dans ce rayon autour de l’impact et qui possède un IDamageable subit les dégâts, y compris la cible, une seule fois. Affichez ensuite l’explosion : instanciez un blastPrefab sérialisé (un GameObject) à l’impact, redimensionnez-le à Vector3.one * data.splashRadius * 2f et détruisez-le après 0.25 seconde. Sans explosion, seule la cible est touchée, comme auparavant.

Le prefab CannonBall contient l’explosion dans son blastPrefab. Appuyez sur Play, placez un Cannon là où les ennemis se regroupent, puis cliquez sur Check.

Essayez vous-même

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

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Jeu Unity : défense de tours