Generating a level from an image in Unity3D

Written by ResistanceStdio | Published 2018/01/20
Tech Story Tags: programming | gamedev | unity | indie-game | game-development

TLDRvia the TL;DR App

Our levels are made by different blocks that act as tiles. It is a bit of a pain to hardcode all the positions not only for me, the developer, but also for the game designer.

I needed something that made designing and testing a level fast enough. And independent of the developer. So the game designer could just put a file in Unity that will be read and the level will appear on the screen.

I though of how to do this for a while. I first though of JSON files. I come from the mobile apps world and I’m so used to use JSON for everything that it seemed logical to use it here too.

But later on, the game designer came with a much better idea. Why not use an image? It is way more visual and it can be small enough so it doesn’t take too much space. So I decided to use that approach.

How to use an image to generate a level?

The idea is quite simple: read 1 pixel from the image, decode de color and put a tile in that position. The image will be the number of tiles for the width x the number of tiles for the height.

So we’ll go from this:

To this:

The generated level

Disclaimer: all the assets I am using for these examples are from Kenney Game Assets 2. Thanks from here to Kenney for providing such awesome assets :) If you like them, consider getting one of his packs.

Our assets

We’ll generate a level in the middle of the background for testing purposes. So if this is our background image:

Our beautiful grassy background

We’d like to put the tiles in what would be the checked area of this other image:

The checked area is where the level will be drawn

This is just to draw them in the middle. I chose that number of tiles and position for no particular reason so feel free to adapt to what your game requires.

These are the tiles that will be used: a girl for the player (blue pixel in our level map texture), a zombie (green pixel), fire (red pixel), sand (yellow pixel) and stone (grey pixel)

The tiles that will be used

Let’s get coding

I’m not going to enter in details of how Unity works, so I’ll only explain the code concerning to this topic which is generating a level from an image.

I have a GameObject in my scene which contains my LevelGenerator script. This script has the following public variables (so I can adjust from the editor certain parameters):

Then in our Start method we get one single call to our GenerateLevel method. This is how it looks like:

We loop through the width and height of the texture containing the level design. Then we get the pixel color and we check which object is the one that represents that color. If there’s no object for that pixel color the GetGameObject method will return null and then we’ll just continue to the next pixel. This will happen when reading the pixel for the background (white in my case).

Once we get the object name that we’ll instantiate, we need to know it’s position. For that we have 2 methods: one converting from tiles to the point in pixels in the background (which also considers the startingPosition variable shown above) and another one converting that pixel position into a Vector3 world position.

After that it just instantiates the object in that position and the loop continues until the end of the texture.

Let’s look at the other 3 methods used there:

I think the code is pretty self explanatory here.

The first method just turns x,y tiles from the level design texture into pixel positions in the background.

The second method turns those pixel position into game world points.

The third one is just a giant switch with the color codes of our tiles and their corresponding prefab name.

Level Generation in process! The left image, has been zoomed. In reality it’s 11x6px

With this code we have finally gotten our level from that small image.

I hope this code can help somebody who wants to do something similar to what we do. If you have any questions please feel free to ask.


Published by HackerNoon on 2018/01/20