Here’s a quick way to create a repeating tiled background in Unity. I’m using this technique in a project at the moment, and it works well, however, I’m not sure how if it will scale up for larger games. At the very least it can be used in prototyping.
How the Technique Works
- Define an area that needs to be covered by tiles.
- Calculate how many rows and columns of the tile sprite are needed to fill in the area and instantiate the rows and columns of tiles.
The goal is for any place where the camera background is visible to be covered by a tiled sprite.
Do it Yourself
Create the Background Object
Create a Unity project or open an existing one. Add a handful of random objects to the scene to stand in for game content.
Create a new
called Background and give it a child
and modify its size to cover the area you want the tiled background to appear.
- Put the collider on its own layer and disable collisions with all other layers. This will reduce any chance of issues with unwanted collisions or reduced performance.
- Make sure the
Offset values for the collider (in the Inspector) are zero (i.e. make sure the collider is centred relative to the transform’s position). The calculations for the tile positions assume the collider is centred.
- Make the collider a little bit larger than the area being covered to account for rounding errors when calculating the number of tiles required.
Create a new script called
and paste in the following code:
public class TiledBackground : MonoBehaviour
private GameObject tileObject;
private BoxCollider2D canvasCollider;
canvasCollider = GetComponent<BoxCollider2D>;();
Vector2 canvasSize = canvasCollider.bounds.size;
// instantiate one tile to measure its size, then destroy it
var templateTile = Instantiate(tileObject, Vector2.zero, Quaternion.identity) as GameObject;
Vector2 tileSize = templateTile.GetComponent<Renderer>().bounds.size;
float tilesX = canvasSize.x / tileSize.x;
float tilesY = canvasSize.y / tileSize.y;
// start placing tiles from the bottom left
Vector2 bottomLeft = new Vector2(canvasCollider.transform.position.x - (canvasSize.x / 2), canvasCollider.transform.position.y - (canvasSize.y / 2));
for (int i = 0; i &amp;lt; tilesX; i++)
for (int j = 0; j &amp;lt; tilesY; j++)
var newTilePos = new Vector2(bottomLeft.x + i * tileSize.x, bottomLeft.y + tileSize.y * j);
var newTile = Instantiate(tileObject, newTilePos, Quaternion.identity) as GameObject;
newTile.transform.parent = transform;
// turn the template’s renderer off
tileObject.GetComponent<SpriteRenderer>().enabled = false;
Attach that script to the
The script measures the collider and calculates how many rows and columns of tiles are needed to cover the area. It then creates the tiles by looping through the rows and columns to place the tiles in a grid covering the required area.
Now expand the
object in the
so you can see its child,
field in the
Now when the script runs it will use that tile.
Finally, add a sprite to the
<span style="font-family: Courier New;">Tile</span>
<span style="font-family: Courier New;">SpriteRenderer</span>
component. This is the sprite that will be tiled, and should therefore be a seamlessly wrapping image (there are a couple of samples in the downloadable project).
- Put the tile sprite on a sorting layer behind other content, as you would normally do with a background.
- Darken the sprite colour/tint so the background is dimmer that the rest of the game. This makes it easier for the player to follow the actual game.
Test the Scene
Play the scene and make sure it’s working (the tiling only happens during runtime).
Here’s a slightly more complex scene using a tiled background from a project I’m working on:
The whole collider area isn’t covered by the tiles
This can happen due to the rounding down when calculating how many rows and columns are required (e.g. if the screen width / tile width is 1.1, it will round down to 1 and only have 1 column when 2 are needed). To fix this, you can simply make the collider a little larger. Alternatively, you could adjust the calculation in the script if you can do it better.
Unity freezes when the scene is played
This can happen if there is no sprite in the Tile SpriteRenderer. Make sure a sprite is in there. You could improve the script by checking for a missing sprite before trying to create the tiles.
The tiles are in front of game content
Put the tile sprite on a sorting layer below other content.
Get the Project
A fully working project is available at the link below, including the exact script code from this post. The project and code is completely public domain (thanks to http://openclipart.org/
for the public domain art.
Project on Project on BitBucket
Feel free to contribute to the code or suggest improvements.