Procedural Cityscape Generation in Unity3D
This project reached it’s goal outlined in the proposal to create a Cityscape procedural generator in Unity3D. I included areas of high rise and some areas of low rise buildings using the Unity perlin noise function. This was mostly to create a sort of urban-flow rather than a completely random cluster of buildings. I also included streets with a random chance of spawning a bench on the path. Another feature I included was park/grassy areas. These grassy areas spawn trees and the trees can be configured to have slight positional variance in order to create a more organic look. Buildings that are generated also have an option for positional variance. All of the buildings, roads, trees and features such as the benches were modelled and textured by myself. I used blender for everything except the trees, for which I used Unity’s built-in tree modeller.
How Does It Work?
The CityScape generator runs on the “BuildCity.cs” script. This script begins by creating a 2D array of integers called “map” of a configured size on which the city will be mapped. A seed can be chosen or a Random Seed option can be enabled, this is used to offset the Perlin Noise. The map array is looped through and filled with returns from the Perlin Noise function with the seed. In order to create more variance amongst the noise generation, the values used to generate it are divided; if this was not done the generation would mostly return the same value. Next a loop runs for the amount of X axis roads configured, through each tile of the map array, replacing the x axis of the given tile with a -1 (signifying an x axis road). Then a loop runs for the amount of Z axis roads configured, through each tile of the map array, replaxing the z axis of the given tile with a -2 (signifying a z axis road). Where a z axis road meets an x axis road, a -3 is placed, signifying a crossroad. Next the map array is looped through in it’s entirety, instantiating the objects into the correct tiles depending on their correlated value in the array. Throughout this process, there are checks in place to see if certain features are available: Park Benches; Trees; Building Positional Variance; Tree Positional Variance etc. and they are instantiated if they are enabled and other operations are applied to them upon instantiation. There are random ranges in place to create tree type variance, tree and building positional variance, if they are enabled.
I am very interested in Game Design and procedural generation. I modelled every single model used, the buildings, grass areas, roads etc. in blender. I didn’t know how to use blender before this assignment and it shows in the amateurish models, however I am now very familiar with it and am comfortable using the keybinds and shortcuts. As for the code, I planned to use a map grid from the start but I got the idea to use negative integers overwriting the noise map in order to inject roads into the generation from a tutorial on youtube by Holistic3D. I am very proud of how the mapping system worked out and how seamlessly the roads are generated. I really enjoyed coming up with a solution for the generation of benches on the sides of roads; ensuring they always faced the street using Quaternion rotations. I also really liked the mini feature of positional variance, this gives the generations a more natural look despite being generated on a grid. I also am very proud of how I managed Tree generation and park areas, limiting it to park areas, and making the distribution natural. The Park areas are seamless and look natural.
Proposed Approach - Progression
Research / References
I’m usually not a huge fan of sifting through documentation but the Unity documentation has already proved invaluable and has been very easy to navigate and find what I need.
- Unity Documentation
- Youtube Videos
- Other References
- Blender (Models)
- Photoshop (Textures)