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 度,每秒的转动速度(以度为单位)乘以 Time.deltaTime,就能得出每帧应转动的角度。
challenge icon

挑战

中等

让每座塔的炮塔朝向目标。

  1. 在 Tower 中,添加 [SerializeField] private Transform head; 和 [SerializeField] private float turnSpeed = 270f;。
  2. 有目标时,只绕 y 轴转动 head,每次最多转动 turnSpeed * Time.deltaTime 度,并使用 Quaternion.RotateTowards。
  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 在线编辑器