Menu
CoddyTech

Урон по области

Урок 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) уничтожает её после этой задержки, и для этого не нужен собственный таймер.

challenge icon

Задание

Средне
  1. В TowerData добавь публичное поле типа float splashRadius: значение 0 означает, что урон по области отсутствует. В CannonData задай значение 1.5.
  2. Измени Projectile.Launch на Launch(Transform target, int damage, TowerData data) и сохрани данные. В Tower передавай данные башни.
  3. При попадании, если радиус урона по области в данных больше 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);
        }
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Игра в Unity: защита башен