Урон по области
Урок 14 из 18 курса Игра в Unity: защита башен на 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добавь публичное поле типа floatsplashRadius: значение 0 означает, что урон по области отсутствует. В CannonData задай значение 1.5. - Измени
Projectile.LaunchнаLaunch(Transform target, int damage, TowerData data)и сохрани данные. ВTowerпередавай данные башни. - При попадании, если радиус урона по области в данных больше 0, каждый коллайдер в пределах этого радиуса от места попадания, у которого есть IDamageable, получает урон — в том числе цель, один раз. Затем покажи взрыв: создай сериализованное поле
blastPrefab(объект GameObject) в месте попадания, измени его масштаб наVector3.one * data.splashRadius * 2fи уничтожь через 0.25 секунды. Если урона по области нет, урон получает только цель, как и раньше.
В префабе CannonBall объект Blast указан в поле blastPrefab. Нажми Play, поставь Cannon там, где скапливаются враги, затем нажми Check.
Попробуйте сами
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);
}
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.