Runtime Mesh Manipulation With Unity

One of the benefits of using Unity as your game development platform is its powerful 3D engine. In this tutorial, you’ll get an introduction to the world of 3D objects and mesh manipulation. By Sean Duffy.

4.8 (31) · 2 Reviews

Download materials
Save for later
Share
Update note: Sean Duffy updated this tutorial for Unity 2019.1.2. Arai Lanju wrote the original.

Welcome to the world of 3D objects and mesh manipulation! One of the benefits of using Unity as your game development platform is its powerful 3D engine. That 3D engine, along with Unity’s ability to use custom editors, makes the development of 3D games and apps so much easier.

With the growth of virtual reality and augmented reality (VR/AR) technology, most developers will inadvertently find themselves wrestling with the gritty bits of 3D concepts. So let this tutorial be your starting point. Don’t worry, there will be no complicated 3D math here — just lots of hearts, drawings, arrows and loads of fun!

Note: This tutorial is intended for users who are familiar with the Unity editor and have some experience with C# programming. If you need to brush up on these topics, check out Introduction to Unity UI and Introduction to Unity Scripting first.

You need to have at least Unity 2019.1.3 installed. You can download the latest version of Unity here.

This tutorial uses a custom editor. You can learn more about custom editors at Extending the Unity Editor.

Getting Started

Understanding Meshes

Time to start with the basic vocabulary of 3D rendering. The shape of a 3D object is defined by its mesh. A mesh is like a net of points, or vertices. The invisible lines that connect these vertices form triangles, which define the basic shape of the object.

Example of a square's mesh.

But in addition to the shape, the engine needs to know how to draw the surface of the object. So a mesh’s data also includes its normals, which are vectors that determine which way a particular triangle is facing, and thus how light bounces off of it. Finally, a UV Map maps a material to an object, specifying how textures wrap around the shape.

In Unity, there are two primary rendering components: The Mesh Filter, which stores the mesh data of a model, and the Mesh Renderer, which combines the mesh data with materials to render the object in the scene.

Got all that? Here’s a cheat sheet for easy reference:

  • Vertices: A vertex is a point in 3D space. Often abbreviated to “vert”.
  • Lines/Edges: The invisible lines that connect vertices to one another.
  • Triangles: Formed when edges connect three vertices.
  • UV Map: Maps a material to an object, specifying how textures wrap around the object’s shape.
  • Normals: The directional vector of a vertex or a surface. This characteristically points outward, perpendicular to the mesh surface, and helps determine how light bounces off of the object.
  • Mesh: Holds all the vertices, edges, triangles, normals and UV data of a model.

Here are the basic steps (in pseudocode) to create a 3D mesh:

  • Create a new mesh named “myMesh”.
  • Add data to myMesh’s vertices and triangle properties.
  • Create a new mesh filter named “myMeshFilter”.
  • Assign myMesh to myMeshFilter’s mesh property.

Setting Up the Project

Now that you have the basics covered, download the project using the Download Materials button at the top or bottom of this page, then unpack the files and open the starter project in Unity. Check out the folder structure in the Project view:

Screenshot of the starter project's folder structure.

  • Prefabs: This contains a CustomHeart prefab, which you’ll use to save your 3D mesh at runtime.
  • Scenes: This contains the three scenes that you will use for the different parts of this tutorial.
  • Editor: The scripts inside this folder give you special powers in the editor during development.
  • Scripts: This contains runtime scripts, or components. When you attach these components to a GameObject, they’ll execute when you click Play.
  • Materials: This folder contains the material for the mesh you’ll be working with.

In the next section, you will create a custom editor to visualize the parts of a 3D mesh.

Poking and Prodding Meshes With a Custom Editor

Open 01 Mesh Study Demo inside RW/Scenes. In the Scene view, you will see a humble cube:

Starting out with a 3D cube.

You’re going to build a custom editor to tear this poor cube apart! (And then you’ll learn how to keep it in one piece.)

Customizing the Editor Script

Select the Editor folder in the Project view. Scripts in this special folder modify how the Unity editor works; they do not become part of the built game.

Screenshot of the Editor folder and its contents.

Open MeshInspector.cs and view the source code. Note that this class inherits from Unity’s base Editor class — that’s what makes Unity understand this is a custom editor rather than a game script.

The first step is to tell Unity what kind of objects that this special editor should draw. Add this attribute on the line above the MeshInspector class declaration:

[CustomEditor(typeof(MeshStudy))]

Now, when any GameObject with the Mesh Study component attached to it is visible in the Scene view, this class will handle drawing it. But right now, you won’t know if that’s happening.

OnSceneGUI is an event method that Unity calls every time it renders the Scene view in the editor. It’s your chance to modify how Unity draws your object in the scene. Add the following at the beginning of OnSceneGUI:

mesh = target as MeshStudy;
Debug.Log("Custom editor is running");

The base Editor class provides a reference to the object you’re customizing in the target variable, which has type Object. You can’t do much that’s useful with a plain vanilla Object, so this code casts target as the type MeshStudy. Logging a message allows you to see in the console that the custom editor is indeed running.

Save the file and return to Unity. Go to the RW/Scripts folder and drag MeshStudy.cs onto the Cube GameObject in the Hierarchy to attach the component to it.

Screenshot showing where to drag MeshStudy.cs.

Look in the console and make sure your code is running. Then go ahead and remove the Debug.Log line so it doesn’t flood your console.

Cloning a Mesh

When you’re working with a 3D mesh with a custom editor in Edit mode, it is easy to accidentally overwrite Unity’s default mesh — that is, the built-in Sphere, Cube, Cylinder and so on. If that happens, you’ll need to restart Unity.

Image of a frustrated face.

To avoid this, you’ll clone the mesh before making any changes to it in Edit mode.

Open MeshStudy.cs. This script inherits from MonoBehaviour, so its Start will not run in Edit mode. Luckily, that’s easy to fix!

In MeshStudy, above the class declaration, add the following:

[ExecuteInEditMode]

When a class has this attribute, its Start will fire in both Play mode and Edit mode. Now that you’ve added it, you can instantiate and clone your mesh object before changing anything.

Add the following code to InitMesh:

meshFilter = GetComponent<MeshFilter>();
originalMesh = meshFilter.sharedMesh; //1
clonedMesh = new Mesh(); //2

clonedMesh.name = "clone";
clonedMesh.vertices = originalMesh.vertices;
clonedMesh.triangles = originalMesh.triangles;
clonedMesh.normals = originalMesh.normals;
clonedMesh.uv = originalMesh.uv;
meshFilter.mesh = clonedMesh;  //3

vertices = clonedMesh.vertices; //4
triangles = clonedMesh.triangles;
isCloned = true; //5
Debug.Log("Init & Cloned");

Here’s what’s happening:

  1. Grabs whatever mesh you’ve originally assigned in MeshFilter.
  2. Creates a new mesh instance called clonedMesh and sets its properties by copying the first mesh.
  3. Assigns the copied mesh back to the mesh filter.
  4. Updates local variables, which you’ll need later.
  5. Sets isCloned to true; you’ll reference this later.

Save the file and return to Unity. The console should show the message “Init & Cloned”.

Select Cube in the Hierarchy and look at the Inspector. The Mesh Filter will show a mesh named clone. Great! This means you have cloned the mesh successfully.

Screenshot showing the cloned mesh filter in the Inspector.

But notice there’s no new Mesh asset in your project — the cloned mesh only lives in Unity’s memory right now, and it will disappear if you close the scene. You’ll learn how to save a Mesh later.