Menu
CoddyTech

Aim

Lesson 10 of 25 in Coddy's Unity Game: Tower Defense course.

A tower turns to face its target: not the whole tower, which stands on its pad, but its head, a child object that carries the barrel. Turning a child turns everything under it and leaves the parent as it is.

The enemies walk lower than the heads, so the direction from a head to its enemy points a little down, and a head that looked straight along it would tip forward. Setting the direction's y to 0 keeps it level, so the head turns around the vertical axis only. A lighthouse lamp that follows a ship:

Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);
Quaternion.LookRotation(direction) is the rotation that faces that direction, so the lamp snaps to the ship at once. A tower head should turn at a speed instead: Quaternion.RotateTowards(from, to, maxDegrees) from the Rotation chapter turns by at most maxDegrees, and a turn speed in degrees per second times Time.deltaTime gives each frame's share.
challenge icon

Challenge

Medium

Turn each tower's head to face its target.

  1. In Tower, add [SerializeField] private Transform head; and [SerializeField] private float turnSpeed = 270f;.
  2. With a target, turn head toward it around y only, by at most turnSpeed * Time.deltaTime degrees, with Quaternion.RotateTowards.
  3. Fire from the barrel: head.position + head.forward * 0.6f.

Press Play: the heads follow the enemies and shoot from the barrel. Then Check.

Try it yourself

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);
    }
}

All lessons in Unity Game: Tower Defense

Practice on your own: Unity playground