Menu
CoddyTech

범위 공격

Coddy의 Unity 게임: 타워 디펜스 코스 레슨. 25개 중 20번째.

Cannon의 포탄은 착탄 지점에서 폭발해 폭발 범위 내의 모든 적에게 피해를 줍니다. 대상만 피해를 입는 것이 아닙니다. Physics.OverlapSphere(center, radius)는 center에서 radius 이내에 있는 모든 콜라이더를 반환합니다. 적뿐 아니라 지면과 경로도 포함됩니다. 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);
        }
    }
}

폭발 범위는 Cannon의 데이터이므로, 이제 투사체에는 피해량 이상의 정보가 필요합니다. Launch는 포탑의 TowerData도 받습니다. Arrow의 폭발 범위는 0이므로, Arrow의 발사체는 계속 대상 하나만 명중합니다. 피해량은 포탑의 레벨에 따라 달라지므로 별도의 인수로 유지합니다.

폭발 효과는 포탄이 폭발한 위치를 플레이어에게 보여 줍니다. 폭발 범위만큼 넓은 반투명 구체가 0.25초 후 사라집니다. Destroy(blast, 0.25f)는 그 지연 시간 후에 효과를 제거하므로, 직접 타이머를 만들 필요가 없습니다.

challenge icon

챌린지

중급

대포 포탄이 폭발하여 주변의 모든 적에게 피해를 줍니다.

  1. TowerData에 public float splashRadius;를 추가합니다(CannonData는 1.5로 설정). Launch는 세 번째 인수인 TowerData data를 받으며, Tower가 이를 전달합니다.
  2. 도착하면 data.splashRadius > 0일 때 Physics.OverlapSphere(transform.position, data.splashRadius)에 있는 각 IDamageable에 피해를 한 번씩 줍니다. 그렇지 않으면 대상에게만 피해를 줍니다.
  3. 그런 다음 직렬화된 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 게임: 타워 디펜스의 모든 레슨

직접 연습해 보세요: Unity 플레이그라운드