Procedural Terrain Generation – Plane – Part 1

Have you ever wonder how to generate terrain procedurally in Unity? You are in the right place!

In this post, we are going to talk about generating mesh for the terrain.

If you don’t know how a mesh is created, I would recommend checking my last post on exactly that subject.

You will need to have an idea of how to generate a mesh, and you will need to use some math skills here. But don’t worry, we will get through it! 🤓

Generating more than a Quad

Plane is built from combining more quads!

Generating a Quad is nothing hard at all, but how about generating a plane?

Well, a plane is nothing more than a series of quads, right?

Exactly! But I bet you don’t want to write all of the points and triangles by yourself, do you?

Let’s starts with the basics and write down base-code for our mesh generator. Oh, and let’s add an option to control the size of that mesh!

using UnityEngine;

/// <summary>
/// Script that generates a plane with width and depth.
/// </summary>
public class PlaneGenerator : MonoBehaviour
{
    // Reference to the mesh filter.
    private MeshFilter meshFilter;

    // Width of our quad.
    [SerializeField]
    [Range(1, 10)]
    private int width = 2;

    // Depth of our plane.
    [SerializeField]
    [Range(1, 10)]
    private int depth = 2;

    /// <summary>
    /// Unity method called on first frame.
    /// </summary>
    void Start()
    {
        meshFilter = GetComponent<MeshFilter>();
        GeneratePlane();
    }

    /// <summary>
    /// Method which generates plane.
    /// </summary>
    private void GeneratePlane()
    {
        // Creating a mesh object.
        Mesh mesh = new Mesh();

        // Defining vertices.
        Vector3[] vertices;

        // Defining triangles.
        int[] triangles;

        // Defining UV.
        Vector2[] uv;

        // Assigning vertices, triangles and UV to the mesh.
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uv;

        // Assigning mesh to mesh filter to display it.
        meshFilter.mesh = mesh;
    }
}

Now, I think it’s a good idea to see the structure of our mesh. We know that there is a lot of quads, but how they align with each other?

This is how our vertices are placed.
// Defining vertices.
Vector3[] vertices = new Vector3[(width + 1) * (depth + 1)];

int i = 0;
for (int d = 0; d <= depth; d++)
{
    for (int w = 0; w <= width; w++)
    {
    vertices[i] = new Vector3(w, 0, d) - new Vector3(width / 2f, 0, depth / 2f);
    i++;
    }
}

From the last post, we know that Vertices are not enough to draw a mesh. We also need Triangles! 👨‍💻

There is a lot of triangles!
// Defining triangles.
int[] triangles = new int[width * depth * 2 * 3]; // 2 - polygon per quad, 3 - corners per polygon

for (int d = 0; d < depth; d++)
{
    for (int w = 0; w < width; w++)
    {
        // quad triangles index.
        int ti = (d * (width) + w) * 6; // 6 - polygons per quad * corners per polygon

        // First tringle
        triangles[ti] = (d * (width + 1)) + w;
        triangles[ti + 1] = ((d + 1) * (width + 1)) + w;
        triangles[ti + 2] = ((d + 1) * (width + 1)) + w + 1;

        // Second triangle
        triangles[ti + 3] = (d * (width + 1)) + w;
        triangles[ti + 4] = ((d + 1) * (width + 1)) + w + 1;
        triangles[ti + 5] = (d * (width + 1)) + w + 1;
    }
}

With triangles added into the mesh, now Unity can draw it in the 3D environment!

We have our plane!

This looks great, but we can make it better! How? With some sample texture! 👨‍🎨

So our last step here will be to calculate the UV map for our mesh, which at this point will be a piece of cake! 🤓

Here we have a UV map on our plane.
// Defining UV.
Vector2[] uv = new Vector2[(width + 1) * (depth + 1)];

i = 0;
for (int d = 0; d <= depth; d++)
{
    for (int w = 0; w <= width; w++)
    {
        uv[i] = new Vector2(w / (float)width, d / (float)depth);
        i++;
    }
}

Now it’s time to see the results!

Plane with texture on it 🔥

Great! We did it! Congratulations!

What do you think about it? Have you tried generating other meshes earlier? Let me know in the comment section below!

If you want to get notified on future content, sign up for the newsletter!

As always, the whole project is available at my public repository. 🔗

And I hope to see you next time! 🤓

4 3 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x