Ever wanted to create a rogue-like shoot ’em up game like Vampire Survivors? In Part 2 of our guide, we will go through how to create infinite map generation. You can also find Part 1 of our guide here, where we went through how to create movement, animations and a camera for our player character.
A link to a package containing the project files up to Part 2 of this tutorial series can also be found at the end of this article.
Having trouble with fixing bugs for map generation? Check out this topic on our forums, where I document common map generation errors our users commonly run into: [Guide] Notable Map Generation Errors
- Introduction
- Terrain background set-up
- Creating a chunk
- Prop randomizer script
- Map controller script
- Accuracy improvements
- Optimization
- Conclusion
1. Introduction
So as you all know, in Vampire Survivors, every level map is infinitely generated in some way. What that means is that if you continuously travel in a certain direction, you will not loop around nor will you hit a roadblock; you will simply travel forever. So in this part, as the title of the article suggests, we will be tackling exactly that.
Article continues after the advertisement:
2. Terrain background set-up
Before we can get started with any code for our map, we first have to set up our terrain. We’ll begin with the background.
a. Slicing the sprite sheet
We will be using the LPC Terrain Repack as our terrain sprite sheet. It contains a variety of terrain tiles and props which will be helpful in populating our map later on. After extracting the folder, drag and drop this file into the Art folder and rename it to Terrain Sprite Sheet.
Tip: If you are struggling to find art/game assets for your game, I recommend checking out OpenGameArt as they have a lot of good and free game assets. This site has been my go-to for any prototype game assets and it is also where I found this terrain sprite sheet.
Once that’s done, the next thing we have to do is to slice the sprite sheet. Similar to how we sliced the player sprite sheet in the previous part, we first have to change a couple of settings in the Inspector window after clicking the terrain sprite sheet.
- Change the Sprite Mode to Multiple as we need to slice the sheet.
- Change the Pixels Per Unit to 32 to enlarge it.
- Change the Filter Mode to Point (no filter) to make our pixels blocky. (I always recommend using this option when you are working with pixel art)
After making sure your settings is the same as mine as shown below, scroll down and hit Apply to confirm the changes!
Now let’s head into the Sprite Editor by clicking on the button in the Inspector window.
For now, we want to only slice out a few terrain tiles as shown below.
Here’s where things will start to differ from the player sprite sheet. If you recall previously, we had used the Automatic slice option located within the Slice pop-up at the top left of the Sprite Editor. However because all the sprites in our terrain sprite sheet are of different sizes, it’s better to manually slice them.
To do so, hold left click, drag anywhere on the Sprite Editor and release when you have the desired size of your slice. You should now be able to see a blue box with green coordinate points.
Don’t worry if the box is too big/small, you can always resize it by dragging the four blue dots at the corner of the box. Alternatively you can also use the pop-up menu that comes with creating a manual slice located at the bottom right corner to achieve maximum precision. We will use the latter.
Now all we have to do is resize our slice to be the exact same as the desired terrain tiles!
We can begin with number 1 as shown above. Follow my Position values as shown below.
Once you are done with creating the slice for number 1, do the same for 2 and 3.
- Position X: 0, Y: 352, W: 32, H: 32
- Position X: 32, Y: 352, W: 32, H: 32
- Position X: 64, Y: 352, W: 32, H: 32
Hit Apply at the top right to confirm the changes once all 3 terrain tiles have been sliced out!
Close out of the Sprite Editor and head back to your Editor. In your project window you should be able to see the sliced sprites.
Article continues after the advertisement:
b. Creating a tilemap
Let’s now create a background for our terrain. To accomplish this, we’ll be using a Tilemap.
Tip: When working with pixel art, I recommend to use Tilemaps when stylizing your environments as they can be beneficial in many ways. Brackeys has an amazing video explaining tilemaps and their benefits.
Right-click on empty space within the Hierarchy > 2D Object > Tilemap > Rectangular. You should now be able to see a Grid within your Scene view. Rename the Grid in your Hierarchy to be Background Grid and the Tilemap to be Background Tilemap. It’s always good to stay organized like this.
Before we can paint in our tilemap, we first have to create a Tile Palette. Navigate to the Art folder and create a folder called Tile Palettes. We’ll use this to store any future Tile Palettes.
There are 2 main ways to bring up the Tile Palette window. The first of which is to click on the Open Tile Palette button at the bottom right of the Scene view while having your Grid or Tilemap selected.
If you do not see this button, it might be because you are using an earlier Unity Editor version.
That brings us to the second way: which is to simply head to Window at the top of the Editor > 2D > Tile Palette. After your Tilemap window is open, drag and dock it however you like until you are satisfied.
Afterwards, click Create New Palette at the top of the window and it should bring up a pop-up.
Change the name of the Palette to be Background Tiles and make sure the Grid and Cell size is Rectangular and Automatic respectively.
Once all the correct settings are in place, simply click Create. The explorer should now should now show up, now all we have to do is to navigate to our Tile Palettes folder that we created previously and select it.
Before we proceed further, let’s head into the Tile Palettes folder and create a subfolder called Tiles to store all our Tile assets.
Multiselect all of the sliced sprites before dragging and dropping them into the Tile Palette window. Navigate to the Tiles subfolder within the Tile Palettes folder and select it.
Alright great, let’s begin painting our tilemap!
Simply click on any of the tiles within the Tile Palette window we just created and head into the Scene view. To place the tiles all you have to do is left click on the desired cell. You can also click and drag to paint multiple cells in a short time instead of clicking each of them.
Make sure to paint until your entire Game view has been filled with tiles and more. Make sure to choose a good mixture of all 3 tiles so they don’t seem repetitive. For example I’ll paint mine with a 20×20 size so that it is big enough.
Now you can hit the Play button and as you can see, the entire game view should be filled up. If it is not, it may be because your player object is not reset.
c. Common tilemap problems
While painting, you might notice some common tilemap problems. If you did not encounter any of the following problems you may proceed to the next section.
- Gaps in between tiles.
- Lines in between tiles.
Gaps in between tiles like the example shown below usually mean that sizing of the tiles are not uniform.
Double-check the sizing of the tiles and make sure they are the same before proceeding. You will find that the gaps will disappear after inputting the correct settings.
As for lines in between tiles, the problem usually stems from Anti Aliasing being enabled.
Navigate to the Project Settings window by clicking on Edit at the top left corner > Project Settings > Quality. Now under Anti Aliasing, set the dropdown to Disabled.
You should now see that the lines have disappeared!
3. Creating a chunk
Now it’s time for us to create our first chunk. By definition, a chunk is to divide (data) into separate sections. You’ve probably heard the word before from Minecraft or other sandbox games where they define a segment of the world, that’s the exact kind of concept we are aiming for.
These chunks that we will be creating will be used to define not only the background, but the props that are around the world which includes trees, rocks and powerups too.
Create an empty GameObject and rename it to be Terrain Chunk, make sure to also reset it’s Transform. You can do so by clicking on the three dots at the top right of the component and hitting Reset.
Next we want to drag our Background Grid onto the Terrain Chunk to make it a child and create another empty GameObject under the Terrain Chunk and name it Props. These will be used to store any background elements that the player will come across.
With that being said, create an empty GameObject with the name Prop Location 1 under the Props and give it an icon by clicking the cube icon next to the name, I’ll give mine a yellow icon. Make sure to reset the transform of this object as well and move it to anywhere within the bounds of the tilemap. If you can’t see the icon it might be because your Gizmos at the top of the Editor is disabled.
Tip: Icons are a great way of locating and managing empty GameObjects as they make these usually invisible objects, visible in the Scene view.
Create several more Prop Locations and do the same until the entire chunk has been populated enough. Make sure to space them out nicely such that no 2 Prop Locations are right next to each other.
Your Hierarchy and Scene should now look something like this.
Now, you might have guessed it already, but the reason why we are creating these empty GameObjects instead of simply putting the props themselves in these locations is because these will be the spawn points of randomly chosen props.
This is so that every game feels different and it is effective in boosting replayability.
Article continues after the advertisement: