Hello everyone,

I’m currently working on a game in which a stealth mechanic based on enemy fields of view (FOVs) will be included. To implement a visualization of these FOVs, I’ve used procedural mesh geometry, or a fancy way of saying shapes created manually through lines of code, as well as some math.

Since I never needed to manually generate meshes in Unity before, I had to search around for answers on how to do so, which took me longer than it should have. While it didn’t take long to find general answers on mesh generation and general answers on the math required for certain shapes, I spent more time than I think anyone should have to for a common feature in video games.

Since this site is all about bringing complete clarity to concepts that may be lacking in explanations, I will write a series of posts about implementing fields of view, each consisting of one of the following concepts: generating procedural meshes, generating and applying a texture to a 2D cone mesh, and implementing field of view detection of the player.

In this post, we’re strictly going to be talking about creating meshes with code in Unity, including setting vertices, triangles, and others.

 

Overview

When generating a mesh in Unity, the two biggest things we need to worry about are vertices and triangles. The purpose of each can be straightforward, but to clarify, vertices are points along the circumference of our shape just as any vertices, and triangles are used to represent the surfaces of faces of a shape.

Vertices

Just like any geometric shape, the size and shape of the faces are dependent on the vertices, which means that our triangles are dependent on the vertices. For example, to create a square, we’ll need four vertices equally distant from each other to represent a face, which of course would look something like this:

procedural-mesh-illustration1

Now, to define the surface of the face we just conceptualized, or its visual representation, we’ll want two equally sized triangles with hypotenuses facing each other. We need our triangles to look like this relative to our vertices:

procedural-mesh-illustration2

In the illustration, the red and green triangles represent the two triangles used to represent the face on our mesh. You’ll also notice the red and green numbers next to the vertices which represent the indices of the vertices used as the vertices for their respective triangles.

To clear up what that means, we have to understand the technical of the vertices and triangles data structures in Unity. Vertices are of course represented by an array of vectors representing positions of vertices stored by index.

 

Triangles

Triangles are a little bit less straightforward as they are represented by an array of integers. Basically, every three integers in the triangles array represent one triangle with vertices referred to by index in the vertices array. Here’s a quick illustration of how it works:

proceduralmeshillustration3As you can see in the picture, three elements from the triangles array group into one triangle with points referenced from the vertices array by index.

Putting it in Practice

If you want to try this out for yourself, create a GameObject with a Mesh Renderer component and a Mesh Filter component, write a script that creates a mesh, and assign the Mesh Filter’s mesh attribute this newly generated one. You’ll need the following lines of code:

 

private void Start() {

Mesh square = new Mesh();

Vector3 topLeft = new Vector3(0, 1, 0);
Vector3 bottomLeft = new Vector3(0, 0, 0);
Vector3 topRight = new Vector3(1, 1, 0);
Vector3 bottomRight = new Vector3(1, 0, 0);
square.vertices = new Vector3[] { bottomLeft, topLeft, bottomRight, topRight };

square.triangles = new int[] { 0, 1, 2, 0, 2, 3 };

GetComponent<MeshFilter>().mesh = square;

}

 

After running with this code, you should now see a newly generated (hot pink) 2D square mesh in your game!

UPDATE:

By the way, I’ve uploaded a video all about creating procedural meshes to create custom shapes on the Xenfinity YouTube channel! Check it out here:

Until next time,

Bilal