Flächenschaden
Lektion 20 von 25 im Kurs Unity-Spiel: Tower Defense von Coddy.
Die Granate der Kanone explodiert dort, wo sie landet, und fügt jedem Gegner in der Nähe der Explosion Schaden zu, nicht nur ihrem Ziel. Physics.OverlapSphere(center, radius) gibt jeden Collider innerhalb von radius um center zurück: Gegner, aber auch den Boden und den Weg. Jeder Collider, der über ein IDamageable verfügt, erleidet den Schaden. Das Ziel ist eines davon, da die Granate auf ihm landet, also darf es nicht zusätzlich ein zweites Mal getroffen werden. Eine Bombe, die jede Kiste in ihrer Umgebung zurückstößt:
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);
}
}
}Der Explosionsradius ist Teil der Daten der Kanone, daher braucht ein Projektil jetzt mehr als nur eine Schadenszahl: Launch erhält auch die TowerData des Turms. Der Explosionsradius eines Pfeils beträgt 0, sodass seine Schüsse weiterhin nur ihr Ziel treffen. Der Schaden bleibt ein separates Argument, da er von der Stufe des Turms abhängt.
Eine Explosion zeigt dem Spieler, wo die Granate detoniert ist: eine durchsichtige Kugel, so breit wie der Explosionsradius, die nach einer Viertelsekunde verschwindet. Destroy(blast, 0.25f) zerstört sie nach dieser Verzögerung, ganz ohne eigenen Timer.
Aufgabe
MittelKanonenkugeln explodieren und verletzen jeden Gegner in der Nähe.
- Füge in
TowerDatapublic float splashRadius;hinzu (CannonData legt den Wert auf 1.5 fest).Launcherhält ein drittes Argument,TowerData data, das der Turm übergibt. - Bei der Ankunft erleidet jedes IDamageable in
Physics.OverlapSphere(transform.position, data.splashRadius)einmal Schaden, wenndata.splashRadius > 0; andernfalls nur das Ziel. - Zeige dann dort ein serialisiertes
blastPrefaban, skaliert mitVector3.one * data.splashRadius * 2f, und rufeDestroy(blast, 0.25f)auf.
Drücke „Spielen“: Eine Kanonenexplosion verletzt dicht gedrängte Grunts. Drücke dann „Prüfen“.
Probier es selbst
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);
}
}
}
Alle Lektionen in Unity-Spiel: Tower Defense
Übe selbstständig: Unity-Playground