Avoiding GC Allocations on a Dynamic Mesh

I’m using Marching Squares to create a dynamic mesh that is (potentially) updated every frame. For assigning the Mesh Verts and Tris I’ve tried a few different routes and ran into various problems. The issue stems from the fact that the number of verts and tris will change as the Marching Squares data changes.

Method A: create generic Lists that hold the vert and tri info and then assign them with mesh.vertices = vertices.ToArray();
obviously this is no good since ToArray() will generate garbage;

Method B: create arrays large enough to hold the max number of tris and verts. This way I can just do

mesh.vertices = vertices;
mesh.triangles = triangles;

the problem here is that my mesh will potentially have a ton more verts and tris than it actually needs which is not ideal

Method C: I also tried using Method B and making a copy of only the tri/vert indexes that are actually populated

copiedTriangles = new int[triCount];
for (int i = 0; i < triCount; i++)
{
      copiedTriangles[i] = triangles[i];
}
        mesh.triangles = copiedTriangles;

but now I get allocations again since I’m creating a new array every time.

Is there a good solution to this problem or will I just have to live with having a bunch of wasted space in all of my meshes?

Did you try using this:

mesh.SetVertices(vertices);

I am not sure now how this method works, but I know that I had the same problem.

GPUs will skip degenerate triangles (ie probably won’t cost perf) if you give them the same vert index, so having larger than you need might be ok. Or perhaps Unity can allow us to pass a range, which would solve it… using Array.Clear for the range. Should be similar to memset.

As OneDragutin said, they’ve added List overloads to some of the functions. Not sure what the performance overhead would be though, compared to int[ ] etc. (Argh that set triangles overhead with all its checks)

Ah right, well make sure you create your List with maximum amount of elements so it doesn’t resize the array internally.

Ok looks like SetVertices and SetTriangles works with no allocations. Awesome! How long have those methods been in the API?
Seriously though I can’t believe I wasted all that time converting all of my vert/tri lists to arrays :frowning: Too bad it seems like there isn’t something similar for setting polygoncolider2D paths

Thanks for the help all!

Not sure but I think since 5.2, maybe 5.1.