So last time I talked about how I learned about the Voronoi algorithm to create the terrain generator in a Winforms project. Then I had to go and actually put that into Unity, originally we’d just had a flat green plane for the ground with some default cities. That marked a large change that game would be going through, there were a few important things I needed to do. First I needed to actually create a mesh of the terrain based on the data, that needed to actually be chunked since a Unity mesh has a maximum vert count of about 65,000. Aside from that I would actually need to replace the cities and locations in the game with new randomly generated ones that could be created dynamically.
So the first step was to create the mesh, originally I thought this would be pretty easy. Go through the array of my Cell class (which held all sorts of data from position, to height, to biome) and create two triangles to make a square piece. Then have those triangles match up with their neighbors to connect to each other.
Something I found out very quickly however was the issue of converting a square Winforms grid I created to some 3D generated mesh. It looked really spiky and sharp. Since I was just connecting the verts together it wasn’t very smooth because they were large cell chunks. So what I added a detail level option to the inspector of the terrain generator, and this increases the amount of verts per cell area. So normally one cell is 1, 1×1 sized quads. When I increase that detail level to 2, it’s now 4 0.5×0.5 sized quads.
This allows me to increase the detail, but I was still only connecting the outer verts to the other cells, this results in it looking extremely box based.
What I ended up doing is doing a QuadLerp on the height of each corner of each vert that was created, this created a great smoothing effect that looked great. The textures were still squares, but that would later just be replaced with blended textures.
public float QuadLerp(float a, float b, float c, float d, float u, float v)
float abu = Mathf.Lerp(a, b, u);
float dcu = Mathf.Lerp(d, c, u);
return Mathf.Lerp(abu, dcu, v);
That allowed me to dynamically create unique worlds whenever I needed. To create a world at a size of 200×200 Unity units, it takes about 15 seconds, this can probably be improved in the future. Next I started the process of integrating the existing game into this new world. You can read about that here.
2 comments on “TC – Terrain Generation Unity Implementation”Add yours →