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
MediumTurn each tower's head to face its target.
- In
Tower, add[SerializeField] private Transform head;and[SerializeField] private float turnSpeed = 270f;. - With a target, turn
headtoward it around y only, by at mostturnSpeed * Time.deltaTimedegrees, withQuaternion.RotateTowards. - 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