Menu
CoddyTech

範囲攻撃

Coddyの「Unityゲーム:タワーディフェンス」コースのレッスン 20/25。

Cannon の砲弾は着弾地点で爆発し、標的だけでなく爆発の近くにいるすべての敵にダメージを与えます。Physics.OverlapSphere(center, radius) は、center から radius 以内にあるすべてのコライダーを返します。敵だけでなく、地面や経路も含まれます。IDamageable を持つ各コライダーがダメージを受けます。標的もそのうちの1つです。砲弾は標的に着弾するため、標的自身が2回ダメージを受けないようにする必要があります。周囲のすべての木箱を吹き飛ばす爆弾の例:

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 なので、その弾はこれまでどおり標的だけに命中します。ダメージは砲塔のレベルによって変わるため、別の引数のままにします。

爆発エフェクトは、砲弾が爆発した場所をプレイヤーに示します。爆発範囲と同じ幅の半透明の球体が、0.25秒後に消えます。Destroy(blast, 0.25f) は指定した遅延の後にオブジェクトを破棄するので、自分でタイマーを用意する必要はありません。

challenge icon

チャレンジ

中級

大砲の砲弾が爆発し、近くにいるすべての敵にダメージを与えます。

  1. TowerDataにpublic float splashRadius;を追加します(CannonDataでは1.5に設定します)。Launchは3つ目の引数TowerData dataを受け取り、Towerから渡します。
  2. 到着時にdata.splashRadius > 0なら、Physics.OverlapSphere(transform.position, data.splashRadius)内の各IDamageableに1回ずつダメージを与えます。それ以外の場合は、対象だけにダメージを与えます。
  3. 次に、シリアライズされたblastPrefabをその場所に表示し、Vector3.one * data.splashRadius * 2fの大きさにして、Destroy(blast, 0.25f)を実行します。

「プレイ」を押します。Cannonの爆発で、密集した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プレイグラウンド