Menu
CoddyTech

範囲攻撃

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

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を追加します。0なら範囲攻撃なしです。CannonDataには1.5を設定します。
  2. Projectile.LaunchをLaunch(Transform target, int damage, TowerData data)に変更し、dataを保持します。Towerでは、タワーのdataを渡します。
  3. 着弾時、dataの範囲攻撃の半径が0より大きい場合、着弾地点からその半径以内にあるIDamageableを持つすべてのコライダーに、対象も含めて1回ずつダメージを与えます。続いて爆発エフェクトを表示します。シリアライズされた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ゲーム:タワーディフェンスのすべてのレッスン