Before writing about split mesh optimization I would like share a simple example that generates a mesh from scratch in Unity. The example is in C# and for Unity since I use it in my project 🙂
Generating a mesh allows manipulating of existing scene meshes or creation of new ones. For example, when splitting a mesh in half we have to modify the mesh of the original game object (since it is ”losing” a part) and create a new mesh for a new GameObject (the detached part).
In the following example I create a pyramid mesh and a GameObject to bring that mesh to the scene. We start by creating a new Mesh object:
Mesh newMesh = new Mesh();
Once we have a mesh we have to define its geometry. A mesh consists of one or more triangles. A triangle is formed by joining three vertices. So we need a bunch of vertices to create triangles. To create a pyramid we need four vertices: three for the base and one for the tip:
Vector3 vertices = new Vector3; // Pyramid base vertices vertices = new Vector3(-1.0f, 0.0f, 0.0f); vertices = new Vector3(0.0f, 0.0f, -1.5f); vertices = new Vector3(1.0f, 0.0f, 0.0f); // Pyramid tip vertex vertices = new Vector3(0.0f, 1.0f, -0.8f);
Now we have vertices, let’s create the triangles! A common practice to specify triangle vertices is with indices that point to the vertex array:
int numTriangles = 4; int triangleIndices = new int[3 * numTriangles]; // Botton triangle triangleIndices = 0; triangleIndices = 1; triangleIndices = 2; // Side triangles triangleIndices = 0; triangleIndices = 3; triangleIndices = 1; triangleIndices = 1; triangleIndices = 3; triangleIndices = 2; triangleIndices = 2; triangleIndices = 3; triangleIndices = 0;
Now we have one array that contains the vertex positions and one array that specifies the triangles. Next we have assign them to the mesh:
newMesh.vertices = vertices; newMesh.triangles = triangleIndices;
Important: as far as I know the size of Mesh.triangles has to be divisible by three.
To bring the new mesh to the scene we need the following:
GameObject pyramidGameObject = new GameObject("PeteThePyramid"); pyramidGameObject.AddComponent<MeshRenderer>(); MeshFilter mf = pyramidGameObject.AddComponent<MeshFilter>(); mf.mesh = newMesh;
MeshRenderer component is needed so we actually see the mesh 🙂 (although without assigning a material to it we see the default magenta ”no material” color when pressing play). MeshFilter binds the newly created mesh to this GameObject.
The triangle that the code above creates should look something like this (wireframe mode in Scene view, paused):
I GIMPed the numbers on top of the triangle to show which vertices (of the array ”vertices”) are which.
When defining triangles with vertex indices the order of the vertices is VERY important. In Unity triangles are defined by listing the vertices in clockwise order (from the camera viewpoint). So the visible triangles in the picture above would be 0-3-1, 1-3-2 and 2-3-0.
If we define the last triangle in counter-clockwise order like this…
triangleIndices = 0; triangleIndices = 3; triangleIndices = 2;
…the winding order of the triangle would be reversed and the triangle would not be visible:
So be careful when defining triangles!
Now we have a simple pyramid mesh in the scene, cool! As you see generating a mesh is fairly simple but I wanted to post this since there cannot be too many examples 🙂
Special bonus to make thing more herp derp:
MeshCollider mc = pyramidGameObject.AddComponent<MeshCollider>(); mc.convex = true; mc.sharedMesh = newMesh; Rigidbody rb = pyramidGameObject.AddComponent<Rigidbody>();
As you probably guessed this makes the mesh a collider and adds a RigidBody component to the new GameObject. A view of the MeshCollider: