In this blog I’ll show how to create a mesh procedurally in Unity. This includes winding order, normals and how to expose your mesh factory to Unity using editor script.

One of the best features of Unity is how smooth the asset pipeline works where 3D models flows seamless from any 3D program into to the Unity scene editor. So why would you create meshes inside Unity? Actually there is a number of reasons:

Additional basic shapes can be used to mock-up a level. Unity already has some basic shapes (Cube, Sphere, Capsule, Cylinder and Plane), than can be used for creating a test-level without needing to open another tool. But why stop here? What about other often used shapes such as staircases, pyramids or cones.

can be used to mock-up a level. Unity already has some basic shapes (Cube, Sphere, Capsule, Cylinder and Plane), than can be used for creating a test-level without needing to open another tool. But why stop here? What about other often used shapes such as staircases, pyramids or cones. Creating level design procedurally . Unity 3 already includes a tree editor, but you can easily create scripts that creates cities, characters and other game props procedurally.

. Unity 3 already includes a tree editor, but you can easily create scripts that creates cities, characters and other game props procedurally. The last reason for creating meshes procedurally is that it is fun. And by creating scripts that generates meshes, you’ll learn a lot about how Unity handles meshes internally.

Understanding the structure of a mesh

A polygon mesh in Unity is created of triangles. The most simple 3D shape is a Tetrahedron – a simple 4 sided shape.

The mesh consist of an array of vertices and indices:

The vertices are Vector3 positions and the triangle faces indices are integers (The illustration above uses one based index, but Unity uses zero based indices). The Tetradron is created by 4 triangles. The first triangle has the vertex indices 1-2-4 (the vertices P1, P2, P4). The triangle must be defined using clockwise polygon winding order – this is used for backface culling (usually only the frontside of every triangle is draw).

By using shared vertices, with each vertex referenced multiple times, a mesh can be created very compact.

The source code for creating a simple Tetrahedron is:

MeshFilter meshFilter = GetComponent(); if (meshFilter==null){ Debug.LogError("MeshFilter not found!"); return; } Vector3 p0 = new Vector3(0,0,0); Vector3 p1 = new Vector3(1,0,0); Vector3 p2 = new Vector3(0.5f,0,Mathf.Sqrt(0.75f)); Vector3 p3 = new Vector3(0.5f,Mathf.Sqrt(0.75f),Mathf.Sqrt(0.75f)/3); Mesh mesh = meshFilter.sharedMesh; if (mesh == null){ meshFilter.mesh = new Mesh(); mesh = meshFilter.sharedMesh; } mesh.Clear(); mesh.vertices = new Vector3[]{p0,p1,p2,p3}; mesh.triangles = new int[]{ 0,1,2, 0,2,3, 2,1,3, 0,3,1 }; mesh.RecalculateNormals(); mesh.RecalculateBounds(); mesh.Optimize();

The code above creates the correct shape, but it has one serious problem. If you create a tethradron in Unity, you will notice that the shading is wrong (see screenshot ‘Shared vertices’). The problem is that the shading uses the vertex normals – and there is one vertex normal for each vertex (The normals are the red line segments – this is rendered using the MeshDisplay component). The normals are calculated using the face normals (using the method RecalculateNormals() ). In this case we want sharp edges and do not want to share vertex normals. This can be done by not sharing the vertices. If you are creating a mesh without sharp edges, you should use shared normals.

The following shows the source code without shared vertices. This means that each corner of the shape has three vertices (one for each normal). This creates the hard edges we want for this shape. On the screen shoot to the right you can see the three normals at each corner.

Source code for unique vertices:

MeshFilter meshFilter = GetComponent(); if (meshFilter==null){ Debug.LogError("MeshFilter not found!"); return; } Vector3 p0 = new Vector3(0,0,0); Vector3 p1 = new Vector3(1,0,0); Vector3 p2 = new Vector3(0.5f,0,Mathf.Sqrt(0.75f)); Vector3 p3 = new Vector3(0.5f,Mathf.Sqrt(0.75f),Mathf.Sqrt(0.75f)/3); Mesh mesh = meshFilter.sharedMesh; mesh.Clear(); mesh.vertices = new Vector3[]{ p0,p1,p2, p0,p2,p3, p2,p1,p3, p0,p3,p1 }; mesh.triangles = new int[]{ 0,1,2, 3,4,5, 6,7,8, 9,10,11 }; mesh.RecalculateNormals(); mesh.RecalculateBounds(); mesh.Optimize();

To add the Tetrahedron object to the GameObject menu in Unity, create a script in the a folder called ‘Editor’ (every script in an Editor folder allows interaction with the Unity Editor).

In this script, create a static function with the annotation MenuItem. This will add the method as a menu item in Unity.

using UnityEngine; using UnityEditor; public class TetrahedronEditor : Editor { [MenuItem ("GameObject/Create Other/Tetrahedron")] static void Create(){ GameObject gameObject = new GameObject("Tetrahedron"); Tetrahedron s = gameObject.AddComponent(); MeshFilter meshFilter = gameObject.GetComponent(); meshFilter.mesh = new Mesh(); s.Rebuild(); } }

The full source code for this project can be found at GitHub:

https://github.com/mortennobel/ProceduralMesh

This includes a simple UV mapping as well as a custom editor for the Tetrahedron component.

Part 2 of this article can be found here:

https://blog.nobel-joergensen.com/2011/04/05/procedural-generated-mesh-in-unity-part-2-with-uv-mapping/