Problems i have encountered:
- Meshes dont keep their submesh material atributes. all submeshes use the last material.
- Meshes combine into each other, cause entire faces to be rendered from one mesh to another.
- Shadows are rendered by mesh, not vertex. So if you have a large map, this is useless.
- Meshes sometimes dont even combine properly. Causing them to be ripped to shreds and combined into other meshes.
- Increases verticies like crazy, my 700k verts went up to 2.8mil verts.
- NEW: also meshes keep their deformed shape when I stop the game. This isnt perminent but it is annoying.
I have about 1.3k objects in a map, I combine each object that is equal to one another together(trees with trees, not trees with building and cars). But all of the above happens. Actually decreasing performance. And im using this because dynamic batching isnt an option at all. 9k calls, 4k of those 9k are batched(causing a bit of an overhead). How ever the only good to come from this, 5k draw calls nd 4k others batched, is now reduced to 250 draw calls and none batched.(about 20-30 tiems better). So this script only works well if there are no shadows.
oh and if you want a copy of the script or can find problems here it is:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[RequireComponent(typeof(MeshRenderer))]
public class Stuff : MonoBehaviour {
void Start(){
Check ();
}
void Check(){
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
List<MeshFilter> Newfilt = new List<MeshFilter>();
foreach (MeshFilter filt in meshFilters) {
if(filt.renderer.materials[0].name == meshFilters[0].renderer.materials[0].name){
Newfilt.Add(filt);
}
}
BatchObjs (Newfilt);
print ("Checking done, " + Newfilt.Count + " objects with same first mat, going to batch them!");
}
void BatchObjs(List<MeshFilter> meshFil) {
GameObject meshon = new GameObject();
MeshFilter[] meshFilters = meshFil.ToArray();
CombineInstance[] combine = new CombineInstance[meshFilters.Length];
List<MeshFilter> newfilts = new List<MeshFilter> ();
int i = 0;
while (i < meshFilters.Length && meshFilters[0].mesh.vertices.Length * i < 64500) {//
newfilts.Add(meshFilters[i]);
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
//following is attributes to combine;
combine[i].mesh.vertices = meshFilters[i].mesh.vertices;
combine[i].mesh.triangles = meshFilters[i].mesh.triangles;
combine[i].mesh.uv = meshFilters[i].mesh.uv;
combine[i].mesh.uv1 = meshFilters[i].mesh.uv1;
combine[i].mesh.uv2 = meshFilters[i].mesh.uv2;
combine[i].mesh.normals = meshFilters[i].mesh.normals;
Destroy(meshFilters[i].mesh);
Destroy(meshFilters[i].gameObject);
meshFilters[i].gameObject.SetActive(false);
i++;
}
//
meshon.gameObject.AddComponent<MeshFilter> ();
meshon.gameObject.AddComponent<MeshRenderer> ();
meshon.GetComponent<MeshFilter>().mesh = new Mesh();
meshon.GetComponent<MeshFilter>().mesh.CombineMeshes(combine,true);
Material[] Mats = new Material[meshFilters[0].renderer.materials.Length];
for (int i2 = 0; i2 < meshFilters[0].renderer.materials.Length; i2++) {
Mats[i2] = meshFilters[0].renderer.materials[i2];
}
meshon.renderer.materials = Mats;
if (GetComponentsInChildren<MeshFilter> ().Length > 0) {
Invoke("Check",.2f);
}
}
}
Below is without my batching. 23 fps, and its laggy and the meshes are saved from the last combine, but they are rendered as reg meshes anyways
Below, after doing the script. If you were on the ground you’d get 18 fps, cause of shadows(calculate per mesh, not vertices) , rendered is much smaller but its will laggy. as well as the meshes deforming into each other(as you can see with all of the red and green lines, which are car hood and tree leaves makeing faces deforming and combining) Also buildings are black or blue because thets their last material, and they dont assign to submeshes.