Menu
CoddyTech

범위 공격

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

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를 추가합니다. 0은 범위 피해가 없다는 뜻입니다. CannonData는 값을 1.5로 설정합니다.
  2. Projectile.Launch를 Launch(Transform target, int damage, TowerData data)로 변경하고 data를 보관합니다. Tower에서 타워의 data를 전달합니다.
  3. 도착했을 때 data의 splash radius가 0보다 크면, 충돌 지점에서 해당 반경 안에 있는 IDamageable을 가진 모든 콜라이더가 피해를 받습니다. 대상도 포함하며, 각 대상은 한 번만 피해를 받습니다. 그런 다음 폭발 효과를 표시합니다. 직렬화된 blastPrefab(GameObject)을 충돌 지점에 생성하고, 크기를 Vector3.one * data.splashRadius * 2f로 설정한 뒤 0.25초 후에 파괴합니다. 범위 피해가 없으면 이전처럼 대상만 피해를 받습니다.

CannonBall 프리팹의 blastPrefab에는 Blast가 할당되어 있습니다. 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 게임: 타워 디펜스의 모든 레슨