- Home /
Combine mesh causes huge memory leak, how to solve?!
Hi,
I have a huge map made out of little pieces, so I'm spawning about ~20,000 simple(and all the same) objects. Obviously this isn't the ideal situation so I want to reduce the drawcalls by combining the mesh for every 10 objects (because I know there is a limit in combining meshes poly count). So this would leave me with an acceptable 2000 objects for the entire map(the map is about 5x5 km in size)
I have this scripts which combines multiple GameObjects into one to have less draw calls.
void CombineMesh()
{
Matrix4x4 myTransform = transform.worldToLocalMatrix;
Dictionary<Material, List<CombineInstance>> combines = new Dictionary<Material, List<CombineInstance>>();
MeshRenderer[] meshRenderers = GetComponentsInChildren<MeshRenderer>();
foreach (var meshRenderer in meshRenderers)
{
foreach (var material in meshRenderer.sharedMaterials)
if (material != null && !combines.ContainsKey(material))
combines.Add(material, new List<CombineInstance>());
}
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
foreach (var filter in meshFilters)
{
if (filter.sharedMesh == null)
continue;
var filterRenderer = filter.GetComponent<Renderer>();
if (filterRenderer.sharedMaterial == null)
continue;
if (filterRenderer.sharedMaterials.Length > 1)
continue;
CombineInstance ci = new CombineInstance
{
mesh = filter.sharedMesh,
transform = myTransform * filter.transform.localToWorldMatrix
};
combines[filterRenderer.sharedMaterial].Add(ci);
Destroy(filterRenderer);
meshFilters = null;
}
foreach (Material m in combines.Keys)
{
var go = new GameObject("CM");
go.transform.parent = transform;
go.transform.localPosition = Vector3.zero;
go.transform.localRotation = Quaternion.identity;
go.transform.localScale = Vector3.one;
var filter = go.AddComponent<MeshFilter>();
filter.mesh.CombineMeshes(combines[m].ToArray(), true, true);
var arenderer = go.AddComponent<MeshRenderer>();
arenderer.material = m;
}
combines = null;
meshRenderers = null;
Resources.UnloadUnusedAssets();
Destroy(this);
Running this on the objects would eat up all my 16GB of ram in my ssytem. I've tried adding combines = null;
and meshRenderers = null;
and Resources.UnloadUnusedAssets();
in the end of the script so it would clean up the garbage.
However, somehow the garbage collector doesn't clean up the mess created. I am even unable to do this on a 32 bit build duo to the 4GB limitations.
How can combine a mesh without eating all my memory?
Thanks in advance,
Kindest regards.
I have run into the same issue. Any solutions would be very helpful!