Unity Custom Editor

This week I have been working on a Unity custom editor, with the goal of making meshes easier to work with.

It made sense to show this editor for the MeshFilter type, since that’s the script unity uses to store the Mesh object on. Anytime the MeshFilter selected in the editor the inspector shows the custom editor inspector.

The plan for the inspector was to show just the details of the Mesh; such as the number of vertices and the number of triangles. This could then be expanded to show the values of the vertices and triangles, and lastly allow them to be live editable.

The first part of the custom inspector; showing the details; was very simple, code shown below.

for (int idx = 0; idx < mesh.vertices.Length; idx++)
{
    string str = string.Format("{0} {1}", idx, mesh.vertices[idx].ToString());
    EditorGUILayout.LabelField(str);
}
int count = 0;
for (int idx = 0; idx < mesh.triangles.Length / 3; idx++)
{
    string str = string.Format(
        "{0}, {1}, {2}",
        mesh.triangles[count++],
        mesh.triangles[count++],
        mesh.triangles[count++]
    );
    EditorGUILayout.LabelField(str);
}

Showing the values of the vertices and triangles was simple. After viewing the output of this I came to the realization that most meshes have many duplicate vertices; hinting to me that an optimize functionality would come in handy. More on this optimization later. Below is the code used to display the mesh details.

public (Vector3[], int[]) Optimize(Mesh mesh)
{
    List<Vector3> verts = new List<Vector3>();
    Dictionary<int, int> nLocation = new Dictionary<int, int>();
    List<int> tris = new List<int>();
    for (int vIndex = 0; vIndex < mesh.vertices.Length; vIndex++)
    {
        Vector3 vert = mesh.vertices[vIndex];
        int idx = verts.IndexOf(vert);
        if (idx == -1)
        {
            idx = verts.Count;
            verts.Add(vert);
        }
        nLocation[vIndex] = idx;
    }
    for (int tIndex = 0; tIndex < mesh.triangles.Length; tIndex++)
    {
        int nLoc = nLocation[mesh.triangles[tIndex]];
        Debug.Log(nLoc);
        tris.Add(nLocation[mesh.triangles[tIndex]]);
    }
    Mesh m2 = new Mesh();
    m2.triangles = new int[0];
    m2.vertices = verts.ToArray();
    m2.triangles = tris.ToArray();
    return (verts.ToArray(), tris.ToArray());
}

After running this code on the Cube mesh the results contain much less vertices, while retaining the original shape.