Menu
CoddyTech

狙う

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

塔は標的の方を向きます。土台の上に立つ塔全体ではなく、砲身を備えた子オブジェクトである頭部が向きを変えます。子オブジェクトを回転させると、その下にあるすべてのオブジェクトも回転し、親オブジェクトはそのままです。

敵は頭部より低い位置を歩くため、頭部から敵へ向かう方向は少し下向きになり、その方向をまっすぐ向いた頭部は前に傾いてしまいます。方向のyを0にすると水平を保てるので、頭部は垂直軸を中心にだけ回転します。船を追う灯台のランプの例です。

Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);
Quaternion.LookRotation(direction)はその方向を向く回転なので、ランプは一瞬で船の方を向きます。塔の頭部は、代わりに一定の速度で回転させます。Rotationの章で説明したQuaternion.RotateTowards(from, to, maxDegrees)は、最大でもmaxDegreesだけ回転します。1秒あたりの回転速度(度)にTime.deltaTimeを掛けると、各フレームで回転する分量が得られます。

challenge icon

チャレンジ

中級

各タワーの砲塔をターゲットの方へ向けます。

  1. Towerに、[SerializeField] private Transform head;と[SerializeField] private float turnSpeed = 270f;を追加します。
  2. ターゲットがいるとき、Quaternion.RotateTowardsを使って、y軸方向のみで、turnSpeed * Time.deltaTime度以内でheadをターゲットの方へ向けます。
  3. 砲身から発射します:head.position + head.forward * 0.6f。

「プレイ」を押します。砲塔が敵を追い、砲身から撃ちます。その後、「確認」を押します。

自分で試してみよう

using UnityEngine;

public class Tower : MonoBehaviour
{
    public float range = 4f;
    public int damage = 2;
    [SerializeField] private Projectile projectilePrefab;

    private Enemy target;
    private float nextShot;

    void Update()
    {
        Enemy found = FindTarget();
        if (found != null && found != target)
        {
            Debug.Log("Target: " + found.name);
        }
        target = found;
        if (target == null)
        {
            return;
        }

        if (Time.time >= nextShot)
        {
            Fire();
            nextShot = Time.time + 1f;
        }
    }

    Enemy FindTarget()
    {
        Enemy nearest = null;
        float nearestDistance = range;
        foreach (Enemy enemy in Enemy.All)
        {
            float distance = Vector3.Distance(transform.position, enemy.transform.position);
            if (distance <= nearestDistance)
            {
                nearest = enemy;
                nearestDistance = distance;
            }
        }
        return nearest;
    }

    void Fire()
    {
        Projectile shot = Instantiate(projectilePrefab, transform.position + Vector3.up, Quaternion.identity);
        shot.Launch(target.transform, damage);
    }
}

Unityゲーム:タワーディフェンスのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド