Setting Up a Stage
45 Mins
Now that we have created towers and enemy Agents with a variety of effects, the next step is to set up a stage where players can build towers to defend a location from those enemies.
Recommended Unity Versions
Setting Up a Stage
Setting Up a Stage in Tower Defense Template
Now that we have created towers and enemy Agents with a variety of effects, the next step is to set up a stage where players can build towers to defend a location from those enemies.

Prototype Level

When creating a game, it is often worthwhile to create placeholder art assets to playtest early design work. This allows us to ensure that systems and level design work as intended before committing time and effort to making high quality art that needs to be changed in the event that the design needs to change.
To show this stage of the development process, the starter kit includes a prototype version of stage 1. The prototype stage is roughly the same as stage 1, but the environment art is much simpler than the final version that is playable in the game. Instead of the complex world geometry of the final stage, the prototype is made up entirely of 3D primitives available in the Unity editor.
When going from the prototype to the final stage, the following technical considerations were made to produce a release-quality stage:

Mesh Extension

The stage mesh was extended to ensure that players would never be able to see outside of the bounds of the playing area.

World Mesh Combination

The stage mesh was broken up into chunks to make sure that it is not too large. Meshes much larger than the camera frustum are inefficient because many verts are drawn offscreen. It is best to try to avoid this while keeping as much of the world combined into fewer meshes to minimize draw calls and frustum culling costs.

Collision Mesh

A single approximate collision mesh was created. This is so that projectiles will hit the world objects, as well as to project the cursor into the world when placing towers.

Removing Non-Visible Faces

Non-visible faces are removed from world objects were removed. For the most part, this includes faces at the bottom of objects. Removing these faces reduces overdraw which can reduce performance, especially on lower-end devices.
The above steps should be considered when transitioning from prototype art assets to final, higher fidelity assets. Following them will result in a stage that is performant and easy to manage. A stage made using these steps will contain all required objects and components to ensure that the stage works correctly.
The rest of this tutorial focuses on the step-by step creation of a stage from a blank Unity scene, and does not extensively cover the process of creating high quality art assets.

Level List

If we want our stage to be accessible to players through the menu systems, we will need to create a level list and add the stage to it. We can achieve this by following these steps:
  • From the Project window select Create > Starter Kit > Level List
  • Add the details of the stage to the LevelList ScriptableObject
The stage will now appear in the Level Select menu in the game.

Understanding the LevelList ScriptableObject

The level list allows us to set the number of stage to be shown in the main menu, and we can set the following information for each stage:


The order in which the stage will appear in the menu.


A title for the stage.


A brief string to give players an idea of what to expect from the stage.

Scene Name

The name of the scene that contains the stage.

Setting Up Geometry

  • Add a large plane to the blank scene created earlier. From the Hierarchy window, Create > 3D Object > Plane
  • Ensure that the plane’s transform position is set to (0, 0, 0)
  • Add 3D objects to the stage to establish the layout. Cubes and cylinders are best for this. From the Hierarchy window, Create > 3D Object > Cube/Cylinder
If we already have a more complex mesh created, we can bypass this step and use that instead.

NavMesh Setup

In order to make the stage geometry navigable, we will need to bake the NavMesh.
  • Select the plane or stage mesh
  • Open the Object tab in the Navigation window
  • Check the Navigation Static option
  • Set the Navigation Area to Walkable
  • Select the 3D objects that Agents shouldn’t pass through
  • Open the Object tab in the Navigation window
  • Check the Navigation Static option
  • Set the Navigation Area to Non-Walkable
  • Bake the NavMesh

Navigation Nodes

For enemies to move around the stage, we will need to set up nodes for them to be able to go from point to point. Nodes are also used to define spawn points and points at which the player home base will take damage, should an agent reach it.
We can create a node by adding a Node component to an empty GameObject. This lets us create a mesh which defines where agents will spawn and provides the agents with a way to select a random point within the Node area to navigate to. Being able to select a random point helps ensure that agents do not cluster to a single point.
  • Create an empty GameObject and name it Navigation Nodes or something similar
  • Create an empty GameObject and make it a child of Navigation Nodes, name it StartNode
  • Add a Node component to the Start GameObject
  • Click the Select/Add Mesh button
  • Adjust the child GameObject mesh to be the desired shape
  • Add a Sphere or Capsule Collider component to the StartNode GameObject
  • Set the Is Collider checkbox to true
  • Ensure that the Collider encapsulates the node mesh
The Node component allows us to add a new mesh, which will create a child object with an Area Mesh Creator component, where we can define preset shapes or add points to the mesh by clicking between its corners in the Scene view. Points can be removed by holding shift and clicking the points.
In order to define the next node in the sequence, we will need to add a node selector component, either a Fixed Node Selector, which sends the enemies to a specific node, or a Random Node Selector, which will select from a weighted list of possible nodes.
  • Create another node using the steps listed above
  • On the StartNode GameObject, add a FixedNodeSelector component
  • Add an element to Linked Nodes and drag the new node into the created field
The above steps can be repeated as necessary, linking nodes in the order Agents should travel to them, to make sure that they will follow the desired path through the level.

Tower Placement Areas

Towers in the Starter Kit require IPlacementAreas for a player to be able to place them within a stage. After adding an implementation of IPlacementArea to an empty GameObject, we will be able to define places where towers can be placed.
The starter kit contains two implementations of IPlacementArea:


SingleTowerPlacementArea is a IPlacementArea that can contain only one tower.
  • Create a new GameObject and call it TowerPlacementArea
  • Add a Sphere Collider to the TowerPlacementArea object
  • Add a SingleTowerPlacementArea component to the TowerPlacementArea object
  • Drag the SinglePlacementTile prefab from Prefabs/UI to the Placement Tile Prefab field
  • Set the TowerPlacementArea’s layer to PlacementLayer


  A TowerPlacementGrid represents a gridded area where the player can place multiple towers.
  • Create an empty GameObject and name it PlacementGrid
  • Add a TowerPlacementGrid component
  • Set the desired dimensions for the grid
  • Drag the PlacementTile prefab from Prefabs/UI to the Placement Tile Prefab field
Unlike the SingleTowerPlacementArea, automatically creates a collider for itself set to the correct size, for input handling.

Adding a Home Base

Enemies do not damage the player’s health when reaching the final node. To remedy this, we’ll need to make some modifications to the final navigation node.
  • Add a PlayerHomeBase component to the final node GameObject
  • Set the home base’s Max and Starting Health
  • Drag the Player SimpleAlignment ScriptableObject into the Alignment field
The Player Home Base has fields to assign Particle Systems. One for a charge effect and another for the attack effect. These are not required.

Understanding the PlayerHomeBase component


Max Health

The maximum health of the player’s home base.

Starting Health

The amount of health the home base will start with.


Refers to the ScriptableObject that defines which objects can target and damage the home base.

Charge Pfx

The Particle System will play while an Agent is charging its attack on the home base.

Charge Sound

The sound will play while an Agent is charging its attack on the home base.

Attack Pfx

The Particle System will play while an Agent is done charging and attacks the home base.

Attack Sound

The sound will play while an Agent is done charging and attacks the home base.
The attack effect will be played at the conclusion of the charge, when damage is applied, if assigned.

Adding a Tower Library

Now that we have created areas where towers can be placed, we need to set up which towers are available in our stage.
  • From the Project window: Create > Tower Defense > Tower Library
  • Drag in Tower prefabs that will be available to the player in this stage

Setting Up Waves

For enemies to spawn, we’ll need to set up waves for them to appear in.
  • Create an empty GameObject and name it Wave Manager
  • Add a WaveManager component to to the Wave Manager object
  • Set the Size field to the number of waves we plan on including.
In order to create waves:
  • Create an empty GameObject and name it Wave1 (replace the number as necessary)
  • Add a Wave component to Wave1
  • Set the Size field under Spawn Instructions to the number of Agents that should appear in the wave
  • For each Agent:
  • Drag the AgentConfiguration ScriptableObject for the type of enemy into the Agent Configuration field
  • Set the Delay To Spawn field to how many seconds should pass after spawning the previous agent before spawning the current one
  • Drag the node that the Agent should spawn at into the Starting Node field
The regular Wave component will only complete the wave once all Agents are destroyed. We can also use a TimedWave component, which provides a Time To Next Wave field, where we can set a fixed time before Agents from the next wave start spawning.
After the waves have been created, add them to elements under Waves in the WaveManager.

Adding a Game Manager

A stage requires a GameObject with a GameManager component in order to end the stage when the player has destroyed all enemies or had their base health depleted.
  • Drag the default Starter Kit GameManager prefab into the Hierarchy view from Prefabs/Managers.
  • Drag the LevelList ScriptableObject into the Level List field

Understanding the GameManager component

Game Mixer

This contains a reference to the audio mixer that the game uses.

Master Volume Parameter

The name of the parameter in GameMixer that controls the overall volume of the game.

Sfx Volume Parameter

The name of the parameter in GameMixer that controls the volume of the sound effects in the game.

Music Volume Parameter

The name of the parameter in GameMixer that controls the volume of the music in the game.

Level List

Here we can set a reference to the list of stages that are to be included in our game.

Adding a Level Manager

The LevelManager manages the state of the game, and is where we can set up some other important features of our stage, such as how much currency the player is given at the start. To add one:
  • Add a LevelManager component to the Wave Manager GameObject made earlier
  • Set the Starting Currency field
  • Drag the TowerLibrary ScriptableObject to the Tower Library field

Understanding the LevelManager component


The LevelManager can optionally enter a special state before the game starts. For example, this could be used to display an establishing cutscene for the stage.
The Starter Kit includes TimedLevelIntro, a very simple timed implementation of the intro that waits for a period of time before beginning the game.
To implement custom behaviour, create a new script that extends from Intro and perform our logic in Start. For example, we might launch a cutscene created using Timeline. Once our intro is complete, we can call SafelyCallIntroCompleted to instruct the LevelManager to continue.

Tower Library

Here we can assign the TowerLibrary scriptable object we made earlier to the stage. Doing this will set the available towers for the stage.

Starting Currency

The Starting Currency field defines the amount of in-game currency the player starts with to spend on towers.

Currency Gainer

We may want the player to be able to earn currency over time while playing the game. The fields in the Currency Gainer are where we can set this up.

Constant Currency Gain Addition

Constant Currency Gain Addition is how much currency will be added to the player’s total each time an addition is made.

Constant Currency Gain Rate

Constant Currency Gain Rate is how many times per second the currency addition occurs.

Home Bases

This field defines the player home base. Enemies will reduce the player’s health if they reach this point. This needs to be set to a reference to the final navigation node, which has a PlayerHomeBase component on it. More on this below.

Environment Colliders

Any colliders set here will be ignored by ballistic projectiles briefly. This can be useful to ensure that they do not collide with small parts of the environment between a Tower and an Agent and explode without hitting an enemy.

Pool Manager

Constantly creating and destroying instances of enemies, projectiles, and passive effects is an expensive operation. Instead of doing this, we can use the Starter Kit’s pool manager. The pool manager is a class that will create and store duplicates of objects so that they can be reused.
  • Add a Poolable component to the Projectiles, Particle Systems, and Agents
  • Create an empty GameObject and name it Pool Manager
  • Add a PoolManager component to the Pool Manager GameObject
  • Drag Prefabs for Projectiles, Particle Systems, and Enemies into the Poolables fields if they will appear in the stage
  • Ensure that the Transform scale of the Pool Manager is set to (1, 1, 1)
Note that spawned enemies are made children of the GameObject with the PoolManager, which means they will inherit its transform values. It is likely that we will want the scale to remain (1, 1, 1), but this can be used should we wish to increase the scale of all enemies.



In this section we will look at the CameraRig component that controls the way in which the camera moves. In later sections we will focus on the UI and input components attached to the GameCamera object.

Adding the Template camera

The Unity Tower defense Template comes with a predefined camera already set up to use in Tower Defense games.
  • Delete the default camera from the scene Hierarchy window
  • Drag the GameCamera prefab from Prefabs/Player/ into the Hierarchy

Understanding the CameraRig component

The GameCamera GameObject has a component called CameraRig, which provides us with a number of ways to adjust how the camera works:

Look and Movement Damp Factors

These two fields control how springy the camera movement will be. The higher this is, the smoother the camera motion will be.

Nearest Zoom, Furthest Zoom, Max Zoom

These fields control the zoom extents of the camera.
Max Zoom is only relevant if Springy Zoom is checked on below. It controls how much further than the Furthest Zoom the player is able to zoom out before zoom is clamped entirely.

Zoom Log Factor

Only relevant if Springy Zoom is checked on below. Determines how "strong" the rubber band effect is.

Zoom Recover Factor

Only relevant if Springy Zoom is checked on below. Determines how quickly the zoom returns to its normal maximum extents after the player releases.

Floor Y

This camera assumes the ground is at a fixed Y level, and this value sets where that plane is in the world.

Zoomed Cam Angle

A reference to a transform that has the camera’s angle when fully zoomed in.

Springy Zoom

Whether zoom rubber bands at the near and far zoom points.

Pan bounds

When the CameraRig is selected, a rectangular area will appear in the scene view with draggable handles at its edges. The camera cannot move outside of this rectangle. We can use the handles to make this area bigger or smaller.

Adding UI


We will want to make certain pieces of information about the current game state available to the player. This includes how much health their base has remaining and how much currency they have to spend on towers.
This section covers how to make sure that information is available to the players, primarily through the use of a UI Canvas and the GameUI component.

UI Canvas

For the UI, create a canvas by right clicking in the Hierarchy view and selecting UI > Canvas. Next, navigate to Prefabs/UI in the Project window and attach the following prefabs as children of the canvas object:
  • TowerControllerUI - This will open a popup when the player clicks the tower, which will give them information about the tower and give them the ability to sell or upgrade the tower.
  • Build Menu - This gives the players a selection of towers to build.
  • PlayerBaseLife - A UI element that displays the Home Base’s current health and how much currency is available to the player.
  • WaveContainer - Displays the number of waves in the current stage.
  • Game Over - When the player destroys all the enemies or has their Home Base’s health reduced to zero, the endgame popup will appear.
  • PauseMenu - Allows the user to pause the game and restart/exit the stage.
  • TowerPlaceConfirmationUI - Allows the player to confirm tower placement on mobile devices.
  • TowerPlaceInvalid - Indicates to players using mobile devices that the location they have placed a tower is not a valid placement area.
The GameUI component on the GameCamera object (added in the previous section) will need references to some of these Prefabs:
  • Drag the RadiusVisualiser Prefab to the Radius Visualizer Controller field
  • Drag the TowerControllerUI Object in the Scene to the Tower UI field
  • Locate the BuildInfo object in the Scene. It is a grandchild of the Build Menu object. Drag this to the Build Info UI field

Understanding the GameUI component

We will need to attach a GameUI component to the GameCamera GameObject. The GameUI component defines UI components that are shown when the player selects, buys, or sells a tower.

Placement Area Mask

This allows us to select the layer that Tower Placement components are on. This allows the game to filter out other layers when placing a tower.

Tower Selection Layer

This is the layer that towers that are already placed exist on. This allows us to filter out other layers when selecting a tower on the grid.

Ghost World Placement Mask

This defines which layers tower ghosts can collide with. When moving tower ghosts around, we want to be able to see the ghost on certain stage colliders as well as on the placement grids themselves.

Radius Visualiser Controller

This holds a reference to a visualiser that displays a tower’s radius when selecting/placing it.


This holds a reference to the TowerUI that displays a tower’s level, DPS, and the buttons to upgrade or sell the tower.

Build Info UI

This references the sliding panel that appears when selecting a tower from the build menu.

Adding Input


In previous sections we focused on setting up the game camera and the UI. Now we will need to make it possible for users to move the camera and interact with the user interface using both keyboard/mouse and touch input systems.

Configuring desktop and mobile control schemes

It is likely that some stages will be too large for a single screen, and players will want to pan the camera to view other parts of those stages. The Template comes with components that make this possible using both keyboard and mouse controls, and mobile touch controls.
The premade template GameCamera Prefab has components that enable multiple different input schemes. They are discussed below.

Understanding the InputController component

The InputController component determines which input system is active. It also fires off events made on input received in any given frame. The GameCamera object has this component attached to it. We will go through its fields below:

Drag Threshold Mouse

This will determine how many pixels must be dragged before the camera pans when using mouse controls.

Drag Threshold Touch

This will determine how many pixels must be dragged before the camera pans when using touch controls.

Tap Time

TapTime sets the maximum time for input to be registered as a tap.

Hold Time

HoldTime sets the minimum time for input to be registered as a hold.

Mouse Wheel Sensitivity

This sets how fast the camera will zoom when the mouse wheel scrolls.

Track Mouse Buttons

This determines how many mouse buttons to track.

Flick Threshold

This defines how far the mouse or touch input needs to move to register a "flick" when panning the camera.

Understanding the TowerDefenseKeyboardMouseInput component

The TowerDefenseKeyboardMouseInput component provides functionality for panning the camera using the mouse and keyboard.

Near Zoom Pan Speed Modifier

This field controls the keyboard pan speed difference between being fully zoomed in versus fully zoomed out.

Screen Pan Threshold

ScreenPanThreshold sets the distance the mouse must be from the screen edge before the camera starts to pan.

Mouse Edge Pan Speed

MouseEdgePanSpeed defines how fast the camera pans when scrolling at the edge of the screen.

Mouse Rmb Pan Speed

MouseRMBPanSpeed defines how fast the camera pans when moving the mouse with the right mouse button held.

Understanding the TowerDefenseTouchInput component

The TowerDefenseTouchInput component provides functionality for moving the camera using mobile touch input and interacting with the UI for the mobile version of the Template.

Near Zoom Pan Speed Modifier

This field controls the keyboard pan speed difference between being fully zoomed in versus fully zoomed out.

Pan Area Screen Percentage

This defines how much of the area around the middle of the screen can be used to pan. When the user is dragging a tower within this area of the screen, the camera will pan.

Pan Speed

This defines how fast the camera moves while panning using touch input.

Flick Decay Factor

How long it takes for the camera to stop moving after a flick.

Confirmation Buttons

This contains a reference to the UI prefab that we want to show players when they have dragged a tower visualizer to a valid placement location.

Invalid Buttons

This contains a reference to the UI prefab that we want to show players when they have dragged a tower visualizer to an invalid placement location.