Monthly Archives: July 2016

Tiled Background

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

  1. Define an area that needs to be covered by tiles.
  2. 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 GameObject called Background and give it a child GameObject called Tile.

Add a BoxCollider2D component to Background and modify its size to cover the area you want the tiled background to appear.

tiled_collider

The green collider box defines the area to have a tiled background

Collider Tips

  • 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.

The Script

Create a new script called TiledBackground and paste in the following code:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(BoxCollider2D))]
public class TiledBackground : MonoBehaviour
{
    [SerializeField]
    private GameObject tileObject;
    private BoxCollider2D canvasCollider;

    void Start()
    {
        canvasCollider = GetComponent<BoxCollider2D>;();
        DrawTiledBackground();
    }

    void DrawTiledBackground()
    {
        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;
        Destroy(templateTile);

        // 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;amp;lt; tilesX; i++)
        {
            for (int j = 0; j &amp;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 Background GameObject.

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 Background object in the Hierarchy so you can see its child, Tile. Drag-and-drop Tile from the Hierarchy into the Tile Object field in the Inspector. Now when the script runs it will use that tile.

Finally, add a sprite to the Tile object’s SpriteRenderer 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).

Sprite Tips

  • 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).

This is a tiled background at runtime

This is a tiled background at runtime

Here’s a slightly more complex scene using a tiled background from a project I’m working on:

tiled_game

Troubleshooting

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/ and http://kenney.nl/ for the public domain art.

Project on Project on BitBucket.

Feel free to contribute to the code or suggest improvements.

Unity School e-book!

I’ve written an e-book! It’s called Build your First Unity Game, and takes you from total Unity noob to a finished Air Hockey game. The book is detailed, and clearly explained – it’s not like those other books that tell you what to do without explaining it.

unity_bookThe ebook is available on the Kindle platform (it has lots of pictures, so a tablet is recommended, but it is fully compatible with Kindles and phones).

 

Check it out on the e-book page.