DEV Community

Cover image for From Code to Shape: A Beginner’s Guide to Unity Mesh Generation
Sivakumar Prasanth
Sivakumar Prasanth

Posted on • Originally published at Medium

From Code to Shape: A Beginner’s Guide to Unity Mesh Generation

If you’ve ever wondered how 3D models are built behind the scenes in Unity. While most developers use imported 3D models, Unity also gives you full control to create meshes directly through code. In this blog, we’ll break down the core components of a mesh and walk through how to create a custom mesh using C#.

Whether you’re aiming to generate procedural terrain, dynamic characters, or just want to better understand Unity’s rendering pipeline, this guide will give you the foundation to start crafting geometry with code.


Before we start writing code to generate a mesh, it’s important to understand the key components involved in rendering geometry in Unity.

Mesh

A Mesh is the fundamental building block for rendering 3D models. It is a collection of vertices, triangles, and UVs that together define the shape and surface appearance of a 3D object. Think of it as the skeleton of a model.

Mesh Filter

The Mesh Filter is a component that holds a reference to a mesh. It doesn’t render the mesh or affect how it looks. It simply passes the mesh data to the rendering system. If the mesh is the blueprint, the Mesh Filter is the middleman that hands it to Unity’s renderer.

Mesh Renderer

The Mesh Renderer is responsible for taking the mesh from the Mesh Filter and drawing it on the screen. It handles materials, shaders, and lighting, determining how the mesh will look in the scene. You can think of it as the artist who paints the mesh and makes it visible to the camera.

In Summary

  • Mesh = The raw data (vertices, triangles, UVs).
  • Mesh Filter = Holds and passes the mesh to be rendered.
  • Mesh Renderer = Renders the mesh with materials and lighting.

Now that we understand what a Mesh, Mesh Filter, and Mesh Renderer are, let’s see them in action.

Step 01: Create an Empty GameObject

Step 02: Add Mesh Filter and Mesh Renderer Components

Step 03: Create a New Material

Step 04: Assign a Texture (Optional for Demo)

Step 05: Assign the Material to the Mesh Renderer


Understanding Vertices, UVs, and Triangles

Before we start coding, it’s crucial to understand the three fundamental building blocks of any mesh: vertices, UVs, and triangles.

Vertices

A vertex is a point in 3D space, defined by a coordinate (x, y, z). When you create a mesh, you define its shape by specifying a set of these points. For example, to make a simple triangle, you need three vertices. To create a square (quad), you need four. Think of vertices as the corners or dots that outline your object’s shape.

UVs

UVs are coordinates that map a texture onto your mesh. While vertices define the shape, UVs tell Unity how to paint it. UV coordinates range from (0, 0) to (1, 1), where (0, 0) is the bottom-left of the texture and (1, 1) is the top-right. Each vertex must have a corresponding UV coordinate to ensure the texture is correctly applied.

Triangles

Triangles define how vertices are connected to form surfaces. Every 3D shape in Unity is made up of triangles. Even quads are just two triangles joined together. A triangle is defined by three indices.

The order of these indices matters. It determines which direction the triangle faces (called the winding order). Unity uses a clockwise order to decide the front face of the triangle. Similarly, If needs to show back face, uses counter clock wise.


Time to Code: Creating a Triangle from Scratch

Step 01: Create a new mesh instance

Mesh mesh = new Mesh();
Enter fullscreen mode Exit fullscreen mode

This initializes a new instance of the Mesh class. This will store all the geometry data (vertices, UVs, and triangles) for your custom shape.

Step 02: Assign the mesh to the MeshFilter component on the current GameObject

GetComponent<MeshFilter>().mesh = mesh;
Enter fullscreen mode Exit fullscreen mode

We get the MeshFilter component attached to this GameObject and assign our newly created mesh to it. This tells Unity to use our custom mesh when rendering.

Step 03: Define arrays for vertices, UVs, and triangles with 3 elements (we’re making a single triangle)

Vector3[] vertices = new Vector3[3];
Vector2[] uv = new Vector2[3];
int[] triangles = new int[3];
Enter fullscreen mode Exit fullscreen mode

We declare three arrays to hold the data needed for the mesh

  • Vertices: the 3D coordinates of each point.
  • uv: the texture coordinates for each vertex.
  • triangles: the order in which the vertices are connected to form a triangle.

Step 04: Set the vertex positions (in local space)

vertices[0] = new Vector3(0, 0, 0);     // Bottom-left
vertices[1] = new Vector3(0, 20, 0);    // Top-left
vertices[2] = new Vector3(20, 20, 0);   // Top-right
Enter fullscreen mode Exit fullscreen mode

These are the positions of the three corners of the triangle in 3D space. They define the shape and size of the mesh. This triangle will appear upright and flat on the XY plane.

Step 05: Set UV coordinates corresponding to each vertex

uv[0] = new Vector2(0, 0);  // Bottom-left of the texture
uv[1] = new Vector2(0, 1);  // Top-left of the texture
uv[2] = new Vector2(1, 1);  // Top-right of the texture
Enter fullscreen mode Exit fullscreen mode

These coordinates determine how the texture is mapped onto the triangle. UVs are in 2D (X and Y), ranging from 0 to 1, and are aligned with the texture’s corners.

Step 06: Define the order of vertices to form the triangle

triangles[0] = 0;
triangles[1] = 1;
triangles[2] = 2;
Enter fullscreen mode Exit fullscreen mode

This tells Unity how to connect the vertices to make a triangle. It connects vertex 0 → 1 → 2 in a clockwise order, which defines the front-facing side.

Step 07: Assign the arrays to the mesh

mesh.vertices = vertices;
mesh.uv = uv;
mesh.triangles = triangles;
Enter fullscreen mode Exit fullscreen mode

Finally, we assign our data to the mesh object. Unity now knows what shape to draw (vertices + triangles) and how to map the texture (UVs).

Full Script: Generating a Simple Mesh in Unity via Code

using UnityEngine;

public class MeshGenerator : MonoBehaviour
{
    private Mesh mesh;

    private void Start()
    {
        // Create a new mesh instance
        mesh = new Mesh();

        // Assign the mesh to the Meshfilter
        GetComponent<MeshFilter>().mesh = mesh;

        CreateTriangle();
    }

    private void CreateTriangle()
    {
        // Define arrays for vertices, UVs, and triangles
        Vector3[] vertices = new Vector3[3]; // A triangle has 3 vertex
        Vector2[] uv = new Vector2[3]; // Each vertex should have a currosponding UV coordinate 
        int[] triangles = new int[3]; // A triangle has 3 indices

        // Set the vertex positions (in local space)
        vertices[0] = new Vector3(0, 0, 0);
        vertices[1] = new Vector3(0, 20, 0);
        vertices[2] = new Vector3(20, 20, 0);

        // Set UV coordinates corresponding to each vertex
        uv[0] = new Vector2(0, 0);
        uv[1] = new Vector2(0, 1);
        uv[2] = new Vector2(1, 1);

        // Define the order of vertices to form the triangle
        triangles[0] = 0;
        triangles[1] = 1;
        triangles[2] = 2;

        // Assign the arrays to the mesh
        mesh.vertices = vertices;
        mesh.uv = uv;
        mesh.triangles = triangles;
    }
}
Enter fullscreen mode Exit fullscreen mode

Visual Output: What Our Custom Mesh Looks Like in Unity

Now It’s Your Turn!

Now that you understand the basics of creating a mesh through scripting — using vertices, UVs, and triangles. Go ahead and experiment with differe nt shapes! Try building quads, pentagons, or even more complex forms. Play around with vertex positions, texture mappings, and triangle orders to see how each change affects the result.

Have fun, and don’t be afraid to get creative!

Find My Demo Project Here


Stay updated with the latest insights and tutorials by following me on LinkedIn. For any inquiries for games or questions, feel free to reach out to me via email. I’m here to assist you with any queries you may have!

Don’t miss out on future articles and game development tips!

Top comments (0)