Mesh generation in Unity3D
I can't comment on the specifics of how efficient your algorithm is, but i can comment on something that is probably more important - assuming you have enough computing power:

Readability and Understandability

if you didn't know anything about Mesh code above, it is very difficult to understand. this means that if you were to look at it in 12 months - would you understand it? this is very important when writing code.

Code

Generally speaking be very suspicious of "if" statements. Whenever you see one you gotta ask: why is that there? if you don't have a good reason, then it might be better of to extract a class and use polymorphism to do the same thing. that way, conditional statements are somewhat isolated from behaviour. that makes things easier to change and somewhat easier to code, but it does come at a price.

Methods

You can hide away some implementation in methods. you've got some methods that are very long that it's not easy for someone unfamiliar with what you're trying to do to make sense of it.

int[] triangles;
if (mesh.triangles.Length == 0)
{
    // there are currently no tiles so create new array match tile count
    triangles = new int[tiles.Count * 6];
}
else
{
    // we already have some tiles so expand the existing array
    triangles = new int[mesh.triangles.Length + (tiles.Count * 6)];
}


you can turn the above into this:

int[] triangles = GetTriangles();


and hide everything in that method. it would already dramatically improve readability

Update

A picture is worth a million words! I can sort of conceptualise what you are trying to do.

Unfortunately i can't comment on the best OOP way because i have a very incomplete pictures but something like this would certainly give you ideas on how to structure code to make it more readable. Without altering what it does.

Secondly - tests - i'm gonna guess that you have written tests for this? if you did then tests will force you to write code more systematically so i highly recommend adding tests.

here is just some basic cutting and pasting - i hope it helps.

Performance

btw - your algorithm looks good enough. but be warned, this type of looping can slow things done if mapLength and width gets too large.

for (int j = 0; j &lt; mapLength; j++)
    {
        for (int i = 0; i &lt; mapWidth; i++)
        {
.....}}

using System.Collections.Generic;
namespace practiceTest
{
    internal class UnityMesh
    {
        private Mesh mesh;
    private void Awake()
    {
        Mesh mesh = CreateMesh();
        this.mesh = mesh;
    }

    /// &lt;summary&gt;
    /// Generates this instance - i don't like the name of this method. it's way too vague
    /// &lt;/summary&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    private Mesh CreateMesh()
    {
        Vector3d vertices = GetVertices();
        Mesh mesh = SetVerticesToNewMesh(vertices);
        return mesh;
    }

    private Mesh SetVerticesToNewMesh(Vector3d vertices)
    {
        GetComponent&lt;MeshFilter&gt;().mesh = mesh = new Mesh();
        mesh.name = "Floor Grid";
        mesh.MarkDynamic();
        mesh.vertices = vertices;

        return mesh;
    }

    /// &lt;summary&gt;
    /// Gets the vertices.
    /// &lt;/summary&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    private Vector3d GetVertices()
    {
        vertices = new Vector3[mapLength * mapWidth * 4];
        int v = -1;

        for (int j = 0; j &lt; mapLength; j++)
        {
            for (int i = 0; i &lt; mapWidth; i++)
            {
                vertices[++v] = new Vector3(i * gridSize, 0, j * gridSize); // bottom left
                vertices[++v] = new Vector3(i * gridSize + gridSize, 0, j * gridSize); // bottom right
                vertices[++v] = new Vector3(i * gridSize, 0, j * gridSize + gridSize); // top left
                vertices[++v] = new Vector3(i * gridSize + gridSize, 0, j * gridSize + gridSize); //top right
            }
        }
    }

    private void Add(List&lt;Vector3&gt; tiles)
    {
        int[] triangles = GetTriangles();

        int index = ApplyTriangleIndices(triangles);

        //apply the new triangles for the tiles the user wants
        index = ApplyNewTriangles(tiles, triangles, index);

        mesh.triangles = triangles;
        mesh.RecalculateNormals();
    }

    private static int ApplyNewTriangles(List&lt;Vector3&gt; tiles, int[] triangles, int index)
    {
        for (int i = 0; i &lt; tiles.Count; i++)
        {
            tri = (int)(tiles[i].z * mapWidth + tiles[i].x) * 4;
            triangles[index++] = tri;
            triangles[index++] = tri + 2;
            triangles[index++] = tri + 1;

            triangles[index++] = tri + 2;
            triangles[index++] = tri + 3;
            triangles[index++] = tri + 1;
        }
        return index;
    }

    private int ApplyTriangleIndices(int[] triangles)
    {
        // get the triangle indices from mesh.triangle and apply them to new array
        int index = 0;
        for (int i = 0; i &lt; mesh.triangles.Length; i++)
        {
            trianglesList.AddRange(mesh.triangles);
            triangles[i] = mesh.triangles[i];
            index = i + 1;
        }
        return index;
    }
}
}