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.
Défi
Moyen- Dans
TowerData, ajoutez unfloatpublicsplashRadius: 0 signifie qu’il n’y a pas d’explosion. CannonData définit la valeur à 1.5. - Modifiez
Projectile.LaunchenLaunch(Transform target, int damage, TowerData data)et conservez les données. DansTower, transmettez les données de la tour. - À 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
blastPrefabsérialisé (un GameObject) à l’impact, redimensionnez-le àVector3.one * data.splashRadius * 2fet 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);
}
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.