Generating a ‘map’
Step One: Create an image to test with
I made a really simple 64x32 size image and just made a platform with some holes in black. I then went over with some yellow and made some 2x2 bricks and darkened the top two a little bit, I plan on using this for a little banner block with a top banner section and a bottom banner section. Then added some red blocks for power-ups or something of that nature.
Step Two: Create a basic editor window
Add a new script in a scripts folder called LevelEditorExtension
Now go to the top menu in Windows->MapGenerator and there we are, we have a custom window that says “Hello, custom windows”
Step Four: Accessing an image
In order to read our image we first have to import it into Unity make sure that there is no compression on it and Read/Write is enabled or else we won’t be able to read it.
It should look like the image above
Now we have to get the image into our script the best way to do this is to create a Texture2D field in our window, so we can select which image we want.
Now you open the window again and you will see a nice little image input. When there is an image in it the console will log “Image Loaded” endlessly
Step Five: Reading the image
Now to actually read the data from the image, this is pretty simple because Unity has a great function that returns all the pixels in the image as an array of Colors just what we need. So we are going to get one of each color in the array by making a list and checking to see if the current color isn’t already in there. If it isn’t we add it, if it is we toss it.
Note the ‘using System.Linq’ at the top, this is necessary to be able to call colors.Contains(). Now when we add the image to our window we should see all the added colors be printed out to the log.
Step Six: Creating the objects to generate
I created some basic prefabs that were a sprite with a 2D collider.
The actual art assets I used were Kenney’s (Asset Jesus) over on Kenney.nl I reccomend looking there for any assets you might need, he provides them for free with a CC0 license. If you use some of his work consider supporting him on Patreon. That way he can keep up the fantastic work.
Step Seven: Combining what we know
Now we can actually get into creating the full thing, we are going to read the map’s colors display them as color fields with an empty object field right below each of them. We will also create a simple ‘struct’ in C# that will hold our color and prefab data in one object. Then once we click a button it will add all of our prefabs to the scene in the correct positions.
The global variables section:
As you see we create a new public class (basically a struct) called LevelObject that takes in a Color and a GameObject in the constructor. Making it easy to store our data in one array and iterate through it.
In this function we define a parent_name input that will be used to create an empty game object to serve as the parent and delete the old one if there is one. We also make sure to only read the image if we don’t have our level_items yet. After that we call the GenerateFields function which will add our Color and Object fields to the GUI. We added a button that will actually generate the level / map when it’s pressed so long as there is an image currently loaded.
Very similar to our old ReadImage except this time we add a new LeveLObject to the list and set colors to null to free some memory.
Very simple we just loop through the LevelObjects list and set the fields.
We make sure to destroy the previous level by using the parent_name and create a new one. We make sure to grab the image width and height to iterate over the x and y positions of the image and assign an object to each of those positions with an offset of the object’s size so they fit right next to each other every time.
Now when you run your code you should have an output like this:
Thanks for reading and as always the code is available on my Github.