Урон по площади
Урок 20 из 25 курса Игра на Unity: Tower Defense на Coddy.
Снаряд Пушки взрывается в месте падения и наносит урон всем врагам рядом со взрывом, а не только цели. Physics.OverlapSphere(center, radius) возвращает все коллайдеры в пределах radius от center: врагов, а также землю и путь. Урон получает каждый коллайдер, у которого есть IDamageable. Цель — одна из них, поскольку снаряд падает на неё, поэтому она не должна получать урон повторно. Бомба, которая отбрасывает все ящики вокруг себя:
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);
}
}
}Радиус взрыва — это данные Пушки, поэтому теперь снаряду нужно передавать не только значение урона: Launch также принимает TowerData башни. Радиус взрыва Стрелы равен 0, поэтому её выстрелы по-прежнему поражают только свою цель. Урон остаётся отдельным аргументом, поскольку зависит от уровня башни.
Взрыв показывает игроку, где разорвался снаряд: полупрозрачная сфера шириной с радиус взрыва исчезает через четверть секунды. Destroy(blast, 0.25f) уничтожает её после этой задержки, и для этого не нужен собственный таймер.
Задание
СреднеЯдра пушек взрываются и наносят урон всем противникам поблизости.
- В
TowerDataдобавьpublic float splashRadius;(в CannonData задаётся значение 1.5).Launchпринимает третий аргумент —TowerData data, который передаёт Tower. - При попадании, если
data.splashRadius > 0, каждый IDamageable вPhysics.OverlapSphere(transform.position, data.splashRadius)получает урон один раз; иначе урон получает только цель. - Затем отобрази там сериализованный
blastPrefab, масштабированный доVector3.one * data.splashRadius * 2f, и вызовиDestroy(blast, 0.25f).
Нажми «Играть»: взрыв пушки наносит урон сгрудившимся Grunt. Затем нажми «Проверить».
Попробуйте сами
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);
}
}
}
Все уроки раздела Игра на Unity: Tower Defense
Потренируйтесь самостоятельно: Песочница Unity