Skip to main content

Stage 5: Buying and Placing a Tower

Course progressStage 5 of 10
~45 min
Build

click a tile to spend gold and place an Archer Tower

Learn

how clicking, an affordability check, and Instantiate combine into placement

Ship

towers you buy and drop onto the board

The big idea

You already have clickable tiles from Stage 3 and a gold counter from Stage 4. This stage connects them: clicking a tile should spend gold and grow a tower out of nothing. That last part — making a brand-new GameObject appear while the game runs — is called Instantiate.

To pull this off, the tile's script has to reach into the GameManager and ask "do I have enough gold?" Reaching from one script into another is a cross-script reference. We've been talking to GameManager.instance for a few stages now; here we lean on it harder, asking it to spend and trusting its answer.

When Instantiate makes the tower, we tell it where to appear and which way it faces. The "which way" is a rotation, and "no rotation at all" has a name: Quaternion.identity. You don't need the math behind quaternions yet — just read Quaternion.identity as "facing the default direction, unrotated."

New words
Cross-script reference
When one script reaches into another to read or call something — here, the tile calls GameManager.instance.SpendGold.
Instantiate
Unity's command to create a new copy of a prefab while the game is running.
Instantiate-at-position
Passing a position to Instantiate so the new object appears exactly where you want it.
Quaternion.identity
A rotation that means 'no rotation' — the object faces its default direction.
Prefab
A saved GameObject template you can spawn many copies of.
Before you start

Finish Stage 4: Gold and the HUD — you need a working GameManager with gold, SpendGold, and the on-screen gold counter.

Build it

Step 1 — Make an Archer Tower prefab

A tower has to exist as a saveable template before a tile can spawn it. Build one tower in the Scene, then drag it into your Prefabs folder so Instantiate has something to copy.

Build this GameObject

Archer Tower

2D Sprite
Open recipe
Sprite
a tower sprite from your sliced tilemap
Order in Layer
3 (above tiles, in front of the courtyard)
Position
anywhere for now — the tile decides where it lands
Components to add
  • Sprite Renderer

Drag the finished tower from the Hierarchy into your Prefabs folder to turn it into a prefab, then delete the one left in the Scene. Tiles will spawn copies of the prefab.

You should now have an Archer Tower prefab in your Project window. The Scene itself has no tower yet — that's correct.

Step 2 — Teach the tile to spend gold

Open TileSlot.cs from Stage 3. We extend it in three passes, pressing Play after each so you always know it works before adding more.

Pass 1 — prove the tile can reach the gold. Add two public fields and, inside OnMouseDown, read the gold out of the GameManager:

using UnityEngine;

public class TileSlot : MonoBehaviour
{
public GameObject towerPrefab;
public int towerCost = 50;
public bool occupied = false;

void OnMouseDown()
{
Debug.Log(GameManager.instance.gold);
}
}

Press Play and click a tile. The Console prints your current gold — proof the tile can reach across into the GameManager. Stop.

Pass 2 — spend and spawn. Now make the click charge gold and, if you can afford it, drop a tower:

void OnMouseDown()
{
if (!occupied && GameManager.instance.SpendGold(towerCost))
{
Instantiate(towerPrefab, transform.position, Quaternion.identity);
occupied = true;
}
}

Press Play and click an empty tile. A tower appears on it and your gold drops by towerCost. Click the same tile again — nothing happens, because occupied is now true. Click until you run out of gold, and notice clicks silently stop working. That silence is the problem we fix next.

Pass 3 — give the player feedback. Right now a failed click does nothing, which feels broken. Handle both failure cases out loud:

Script anatomy

The full script, line by line

The finished Stage 5 tile: it spends gold and spawns a tower, and it tells the player why a click was refused.

using UnityEngine;

public class TileSlot : MonoBehaviour
{
public GameObject towerPrefab;
public int towerCost = 50;
public bool occupied = false;

void OnMouseDown()
{
if (occupied)
{
Debug.Log("This tile is taken");
return;
}

if (GameManager.instance.SpendGold(towerCost))
{
Instantiate(towerPrefab, transform.position, Quaternion.identity);
occupied = true;
}
else
{
Debug.Log("Not enough gold");
}
}
}
  1. Lines 5–7What the tile carries

    towerPrefab is which tower to spawn, towerCost is its price, and occupied tracks whether this tile already holds a tower. All public, so you set them per tile in the Inspector.

  2. Lines 11–15Bail out early if taken

    If the tile is already occupied, we log a message and return — leaving OnMouseDown immediately so we never charge gold or spawn a second tower on top.

  3. Lines 17–21Spend, then build

    SpendGold returns true only if the player could afford it AND it already subtracted the gold. So if it's true, we know we can safely Instantiate and mark the tile occupied.

  4. Lines 23–26Broke feedback

    If SpendGold returned false, the player can't afford the tower, so we say so instead of failing silently.

Step 3 — Wire the prefab and cost onto your tiles

Select your tile prefab (or each tile in the Scene). In the Inspector, drag the Archer Tower prefab into the Tower Prefab slot and confirm Tower Cost is 50.

Press Play. Click empty tiles to buy towers; click taken tiles and broke tiles to read the refusal messages in the Console.

Understand it

The key move here is that SpendGold does two jobs at once: it checks whether you can afford the tower and, if so, subtracts the gold — all before it answers true. That's why the whole thing fits in one if. We never charge the player and then discover they couldn't afford it, because the charge and the answer are the same step. Bundling a check and its consequence like this is a common, safe pattern; it removes a whole class of "spent gold but got nothing" bugs.

We also chose a fixed tower with a fixed price instead of a menu of tower types. That's deliberate. One tower keeps the placement logic clear so you can see the click → spend → spawn chain by itself. A tower selector is a great later feature, but it would hide today's lesson behind extra UI.

Try this

Learning beat

Try this

Three short experiments. Predict before you run, then test your guess.

Predict first

Set one tile's Tower Cost to 1000 in the Inspector. Before you press Play, decide: what will clicking it do, and what will the Console say? Run it and check.

Compare

Temporarily delete the if (occupied) block (Pass 1 of this stage's logic) and click the same tile twice. Towers stack on top of each other and you pay twice. Put the guard back. Which version would a player expect?

Connect

Right now the tower just sits there. In Stage 6 it starts firing. What single piece of information would a tower need to know where to send its arrows?

Test your stage

  • Clicking an empty, affordable tile spawns a tower exactly on that tile.
  • The gold counter drops by towerCost when a tower is placed.
  • Clicking a tile that already has a tower prints "This tile is taken" and spawns nothing.
  • Clicking when you're broke prints "Not enough gold" and spawns nothing.
  • Design check. Place a few towers and watch your gold drain. Does 50 feel like a real decision — enough that you can't blanket the board, cheap enough to start defending? Tune towerCost until placing a tower feels like a choice.

If it breaks

  • Nothing happens when I click a tile. The tile needs a Collider2D for OnMouseDown to fire (you added one in Stage 3) and the click must land on the tile, not on something in front of it. Confirm the tile still has its collider.
  • A red error mentions NullReferenceException on GameManager.instance. The GameManager isn't in the Scene, or its instance wasn't set in Awake. Make sure your GameManager object is present and active.
  • A tower spawns but I can't see it. Its Order in Layer is probably at or below the tiles. Set the Archer Tower prefab's Order in Layer to 3 so it draws in front.
  • The tower appears in the wrong spot. Instantiate(towerPrefab, transform.position, …) uses the tile's position. If towers land off-center, your tile's pivot or position is off — check the tile, not the tower.
  • I can place towers for free. The Tower Cost field is 0 on that tile, or you're calling AddGold somewhere by mistake. Confirm Tower Cost is 50.