Creating and Destroying mesh GameObjects quickly fill up RAM
I need to destroy and recreate mesh quickly but everytime I destroy and recreate mesh Unity allocates more RAM and won't let it go. Example of destroying: m_mesh = m_voxelChunk[2,0,2].RequestMesh(); Destroy(m_mesh);
Function request mesh: public GameObject RequestMesh(){ return m_mesh; }
Function recreating mesh: public void CreateMesh(Material mat) { //float startTime = Time.realtimeSinceStartup;
Mesh mesh = MarchingCubes.CreateMesh(m_voxels,2,2);
if(mesh == null) return;
int size = mesh.vertices.Length;
if(m_normals != null)
{
Vector3[] normals = new Vector3[size];
Vector3[] verts = mesh.vertices;
//Each verts in the mesh generated is its position in the voxel array
//and you can use this to find what the normal at this position.
//The verts are not at whole numbers though so you need to use trilinear interpolation
//to find the normal for that position
for(int i = 0; i < size; i++)
normals[i] = TriLinearInterpNormal(verts[i]);
mesh.normals = normals;
}
else
{
mesh.RecalculateNormals();
}
Color[] control = new Color[size];
Vector3[] meshNormals = mesh.normals;
for(int i = 0; i < size; i++)
{
//This creates a control map used to texture the mesh based on the slope
//of the vert. Its very basic and if you modify how this works yoou will
//you will probably need to modify the shader as well.
float dpUp = Vector3.Dot(meshNormals[i], Vector3.up);
//Red channel is the sand on flat areas
float R = (Mathf.Max(0.0f, dpUp) < 0.8f) ? 0.0f : 1.0f;
//Green channel is the gravel on the sloped areas
float G = Mathf.Pow(Mathf.Abs(dpUp), 2.0f);
//Whats left end up being the rock face on the vertical areas
control[i] = new Color(R,G,0,0);
}
//May as well store in colors
mesh.colors = control;
m_mesh = new GameObject("Voxel Mesh " + m_pos.x.ToString() + " " + m_pos.y.ToString() + " " + m_pos.z.ToString());
m_mesh.AddComponent<MeshFilter>();
m_mesh.AddComponent<MeshRenderer>();
m_mesh.GetComponent<Renderer>().material = mat;
m_mesh.GetComponent<MeshFilter>().mesh = mesh;
m_mesh.transform.localPosition = m_pos;
MeshCollider collider = m_mesh.AddComponent<MeshCollider>();
collider.sharedMesh = mesh;
//Debug.Log("Create mesh time = " + (Time.realtimeSinceStartup-startTime).ToString() );
}
Answer by hexagonius · Aug 29, 2015 at 09:41 AM
instead of instantiating a whole new Gameobject every time, alter just the mesh data of the existing Mesh.
http://docs.unity3d.com/ScriptReference/Mesh.html
under 3. the page explains how to recreate a mesh by calling Clear and assigning new data. if done right you won't generate garbage after all meshes have been created once.