Stage 6: Towers That Fire
a tower that fires arrows down its lane on a timer
how a shooter spawns a projectile from a fire point on a cooldown
towers that auto-fire arrows
The big idea
Your tower sits on the board doing nothing. This stage gives it a heartbeat: every so often, it should spawn an arrow. "Every so often" is the important phrase — a tower that fires every frame would machine-gun out hundreds of arrows a second. We want a pause between shots. That pause is a cooldown.
The trick for a cooldown is a timer. Each frame we add Time.deltaTime to a running total. When the total reaches our fireRate (measured in seconds), we fire and reset the total to zero. It's the same Time.deltaTime you learned in Stage 1, used to count time instead of distance.
Arrows also need a sensible spot to launch from — not the tower's center, but its bow or barrel. We make a tiny empty GameObject, a FirePoint, and parent it to the tower. Because it's a child Transform, it moves with the tower automatically, and we ask Instantiate to spawn the arrow at the FirePoint's position.
- Cooldown timer
- A running total of time that triggers an action when it reaches a set amount, then resets — here, the gap between shots.
- Child Transform
- A GameObject nested under another. It moves, rotates, and scales with its parent.
- FirePoint
- An empty child object marking exactly where a tower's arrows should spawn.
- Instantiate-from-Transform
- Spawning an object at another object's position by passing that Transform's position to Instantiate.
- fireRate
- Seconds between shots. Smaller means faster firing.
Finish Stage 5: Buying and Placing a Tower — you need a placed Archer Tower prefab you can spawn onto tiles.
Build it
Step 1 — Make an Arrow prefab
The arrow already knows how to move — it's the same left-to-right motion from Stage 1, just pointed the other way. Build it as a prefab so towers can spawn copies.
Build this GameObjectArrow
2D SpriteOpen recipe
Arrow
2D Sprite- Sprite
- an arrow sprite from your sliced tilemap
- Order in Layer
- 4 (in front of towers and enemies)
- Position
- anywhere — the FirePoint decides where it spawns
- Sprite Renderer
- Projectile.cs (added in Step 2)
Drag the finished Arrow into your Prefabs folder, then delete the one in the Scene. Towers spawn copies of the prefab.
Step 2 — Write the arrow's motion
Add a new script Projectile to the Arrow. This is one short pass — it's a reminder of the Stage 1 motion you already know, aimed right and set to clean itself up.
The full script, line by line
The Stage 6 arrow: it flies right at a steady speed and deletes itself once it leaves the screen.
using UnityEngine;
public class Projectile : MonoBehaviour
{
public float speed = 8f;
public int damage = 1;
void Update()
{
transform.position += Vector3.right * speed * Time.deltaTime;
if (transform.position.x > 10f)
{
Destroy(gameObject);
}
}
}
Lines 5–6Speed and damage live here
speed controls how fast the arrow flies. damage is set up now but isn't used until Stage 7, when arrows start hurting slimes.
Line 10Same motion as Stage 1
Vector3.right is (1, 0, 0). Multiplying by speed and Time.deltaTime moves the arrow 'speed' units per second to the right — your slime motion, mirrored.
Lines 12–15Clean up off-screen
Once the arrow passes x = 10 it's off the right edge and useless. Destroy(gameObject) removes it so arrows don't pile up invisibly and slow the game down.
Drag an Arrow into the Scene by hand and press Play — it should glide right and vanish at the edge. Then delete it; towers will spawn arrows from now on.
Step 3 — Add a FirePoint to the tower
The tower needs to know where its arrows leave from. Add an empty child object positioned at the tower's bow.
Build this GameObjectFirePoint
Empty GameObjectOpen recipe
FirePoint
Empty GameObject- Sprite
- none — it's an invisible marker
- Parent
- Archer Tower
- Position
- a little to the right of the tower's center, e.g. (0.5, 0.2, 0)
- Transform only
Right-click the Archer Tower prefab and choose Create Empty as a child. Because it's a child, it moves with the tower wherever the tower is placed. Apply the change back to the prefab.
Step 4 — Write the TowerShooter
Now the tower's heartbeat. Add TowerShooter to the Archer Tower prefab. We build it in three passes.
Pass 1 — prove the cooldown ticks. First, just make the timer fire a log on schedule — no arrows yet:
using UnityEngine;
public class TowerShooter : MonoBehaviour
{
public float fireRate = 1f;
float timer = 0f;
void Update()
{
timer += Time.deltaTime;
if (timer >= fireRate)
{
Debug.Log("fire!");
}
}
}
Press Play with a tower on the board. After one second the Console starts printing fire! — but notice it then prints every frame, because we never reset the timer. That runaway is exactly the bug the next pass fixes. Stop.
Pass 2 — spawn an arrow instead. Add the prefab and fire point fields, reset the timer, and Instantiate an arrow from the FirePoint:
public GameObject projectilePrefab;
public Transform firePoint;
void Update()
{
timer += Time.deltaTime;
if (timer >= fireRate)
{
timer = 0f;
Instantiate(projectilePrefab, firePoint.position, Quaternion.identity);
}
}
Resetting timer = 0f is what turns a one-time trigger into a steady rhythm. Press Play — once you wire the slots in Step 5, the tower fires one arrow per second.
Pass 3 — the finished shooter. Put it together cleanly:
The full script, line by line
The finished Stage 6 shooter: it counts up to fireRate, fires one arrow from the FirePoint, and resets to do it again.
using UnityEngine;
public class TowerShooter : MonoBehaviour
{
public GameObject projectilePrefab;
public Transform firePoint;
public float fireRate = 1f;
float timer = 0f;
void Update()
{
timer += Time.deltaTime;
if (timer >= fireRate)
{
timer = 0f;
Instantiate(projectilePrefab, firePoint.position, Quaternion.identity);
}
}
}
Lines 5–7What you wire and tune
projectilePrefab is the Arrow to spawn, firePoint is the child marker to spawn it from, and fireRate is the seconds between shots — all public so you set them in the Inspector.
Line 8The timer is private
timer has no 'public', so it stays hidden in the Inspector. It's bookkeeping the tower owns, not a knob the designer turns.
Lines 11–12Count time every frame
Adding Time.deltaTime each frame turns timer into a real-seconds clock that runs the same on any computer.
Lines 13–17Fire and reset
When timer reaches fireRate we reset it to zero first, then spawn an arrow at firePoint.position. Resetting is what creates the steady gap between shots instead of a constant stream.
Step 5 — Wire the slots
Select the Archer Tower prefab. Drag the Arrow prefab into Projectile Prefab, and drag the prefab's own FirePoint child into the Fire Point slot. Confirm Fire Rate is 1.
Press Play, place a tower, and watch it fire one arrow per second down its lane.
Understand it
The cooldown timer is the heart of almost every "do this on a schedule" feature in games — reload times, spawn intervals, ability cooldowns all use this exact shape: count up with Time.deltaTime, act when you cross a threshold, reset. We could have used Unity's InvokeRepeating instead, but the manual timer is worth learning because it's fully under your control and reads top to bottom — you can see precisely when and why a shot happens.
The FirePoint matters more than it looks. By spawning from a child Transform rather than the tower's center, arrows leave from the bow, and because the FirePoint is parented to the tower, it travels along whenever a tower is placed on a different tile. One small invisible object saves you from hard-coding offsets in the script.
Try this
Try this
Three short experiments. Predict before you run, then test your guess.
Set fireRate to 0.2 on one tower and 2 on another. Before you press Play, decide which tower throws more arrows and roughly how many more per second. Run it and count.
Comment out the timer = 0f; line and run it. The tower spews a wall of arrows every frame after the first second. Put the reset back. That single line is the difference between a controlled cooldown and a firehose.
Right now arrows fly straight through slimes harmlessly. In Stage 7 they'll hit. What would the arrow need to detect that it touched a slime, and what would it do when it does?
Test your stage
- A placed tower fires exactly one arrow per second (with
fireRateat1). - Arrows spawn from the FirePoint, not the tower's center.
- Arrows fly right and disappear at the screen edge instead of piling up.
- Changing
fireRatein the Inspector changes how often the tower shoots. - Design check. Place two towers and watch the rhythm. Does one arrow per second feel like a steady defense, or so fast/slow that the lane feels unfair? Pick a
fireRatethat reads as "this tower is working."
If it breaks
- No arrows appear. Most often the
Projectile PrefaborFire Pointslot is empty on the tower prefab. Both must be filled. Also confirm the tower actually placed (Stage 5) and has theTowerShootercomponent. - Arrows spawn but don't move. The
Projectilescript isn't on the Arrow prefab, or you're looking at a stuck arrow. Select the Arrow prefab and confirmProjectile (Script)is attached. - The tower fires constantly, never pausing. You're missing
timer = 0f;. Without the reset, the timer stays pastfireRateforever and fires every frame. - Arrows spawn from the wrong spot. The
Fire Pointslot points at the wrong object, or the FirePoint's local position is off. It should be a child of the tower, nudged toward the bow. - A red error about
firePointbeing null. TheFire Pointslot is empty — drag the tower's FirePoint child into it on the prefab.