So I’ve been recently working on a mobile game that uses procedural mesh generation. I’ve got it working really well, except that the memory is way over the top.

I created a simple test case to demonstrate this issue.

If you post the code below into a GameObject in a blank scene, it will create 16,000 meshes, each with 289 vertices, and 1,536 triangle indices. If we assume that the majority of mesh data is this, and that we are using 4 byte floats and ints, then we can calculate that the size per mesh should end up being about 1536*4 + 289*3 (for each component of the vector) * 4 * 2 (one for normals, the other for the vertex data) which equals 13,080 bytes per mesh. Multiply this by the total mesh count and we get 209,280,000 bytes, or 209.28 megabytes.

If we run the actual code, we end up with over 700 megabytes of RAM used.

Am I misunderstanding something, or is Unity actually creating that much more data for each mesh?

Here is the code so you can try this yourself. Just put it in a blank object in a blank scene, and set the globalMaterial variable to some material from the editor.

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeshTester : MonoBehaviour {
public Material globalMaterial;
const int chunkSize = 16;
// Use this for initialization
void Start () {
InitializeGameObjects();
}
void InitializeGameObjects() {
for (int x = 0; x < 40; x++)
{
for (int y = 0; y < 10; y++)
{
for (int z = 0; z < 40; z++)
{
var g = new GameObject();
g.AddComponent<MeshRenderer>().sharedMaterial = globalMaterial;
g.transform.position = new Vector3(x * chunkSize, y * chunkSize, z * chunkSize);
var mesh = new Mesh();
var verts = new Vector3[(chunkSize + 1) * (chunkSize + 1)];
var tris = new int[chunkSize * chunkSize * 6];
int i = 0;
for (int x1 = 0; x1 < chunkSize + 1; x1++)
{
for (int z1 = 0; z1 < chunkSize + 1; z1++)
{
verts[i] = new Vector3(x1 + x * chunkSize, y * chunkSize + Mathf.PerlinNoise((x1 + x * chunkSize) * 0.1f, (z1 + z * chunkSize) * 0.1f) * 5.0f, z1 + z * chunkSize);
i++;
}
}
i = 0;
for (int x1 = 0; x1 < chunkSize; x1++)
{
for (int z1 = 0; z1 < chunkSize; z1++)
{
tris[(i + 0)] = Get1DIndex(x1, z1);
tris[(i + 2)] = Get1DIndex(x1 + 1, z1);
tris[(i + 1)] = Get1DIndex(x1, z1 + 1);
tris[(i + 3)] = Get1DIndex(x1 + 1, z1 + 1);
tris[(i + 5)] = Get1DIndex(x1, z1 + 1);
tris[(i + 4)] = Get1DIndex(x1 + 1, z1);
i+=6;
}
}
mesh.vertices = verts;
mesh.triangles = tris;
mesh.RecalculateNormals();
g.AddComponent<MeshFilter>().sharedMesh = mesh;
}
}
}
}
int Get1DIndex(int x, int y) {
return y + x * (chunkSize + 1);
}
}
```