public static void CombineMesh(Transform source, Transform target, bool deleteOriginal, bool splitSectors) { var originalPos = source.transform.position; source.transform.position = Vector3.zero; MeshFilter[] allFilters = source.GetComponentsInChildren <MeshFilter>(); List <MeshFilter> meshFilters = new List <MeshFilter>(); for (int i = 0; i < allFilters.Length; i++) { if (allFilters[i] == null || allFilters[i].transform.parent.GetComponent <LODGroup>() != null || !allFilters[i].gameObject.isStatic) { continue; } meshFilters.Add(allFilters[i]); } Dictionary <Point3, List <MeshCombiner> > sectorMeshCombines = new Dictionary <Point3, List <MeshCombiner> >(); List <MeshCombiner> meshCombines = null; MeshCombiner current = null; if (!splitSectors) { meshCombines = new List <MeshCombiner>(); current = new MeshCombiner(); meshCombines.Add(current); } int errorCnt = 0; for (int i = 0; i < meshFilters.Count; i++) { var meshFilter = meshFilters[i]; MeshRenderer meshRenderer = meshFilter.GetComponent <MeshRenderer>(); if (meshRenderer == null) { continue; } meshRenderer.enabled = !deleteOriginal; if (splitSectors) { var secPos = Game.WorldToSector(meshFilter.transform.position); if (!sectorMeshCombines.TryGetValue(secPos, out meshCombines)) { meshCombines = new List <MeshCombiner>(); sectorMeshCombines.Add(secPos, meshCombines); current = new MeshCombiner(); meshCombines.Add(current); } else { current = meshCombines.LastElement(); } } var mesh = Application.isPlaying ? meshFilter.mesh : meshFilter.sharedMesh; if (mesh.GetInstanceID() < 0) //is already combined { continue; } for (int m = 0; m < mesh.subMeshCount; m++) { var matList = Application.isPlaying ? meshRenderer.materials : meshRenderer.sharedMaterials; if (m >= matList.Length || m >= mesh.subMeshCount) { if (errorCnt < 50) { errorCnt++; Debug.LogError( string.Format( "MeshCombine: GameObject {0} is missing a material", meshRenderer.name)); } continue; } Material mat = matList[m]; if (!current.CanAdd(mesh.vertexCount)) { current = new MeshCombiner(); meshCombines.Add(current); } current.AddMesh(meshFilter, mat, m); } } if (splitSectors) { foreach (var combine in sectorMeshCombines) { var created = BuildCombineList(combine.Value, target, deleteOriginal, combine.Key.ToString()); for (int i = 0; i < created.Count; i++) { World.Get <CullingSystem>().Add(combine.Key, created[i]); } } } else { BuildCombineList(meshCombines, target, deleteOriginal, source.name); } source.transform.position = originalPos; if (!deleteOriginal) { return; } for (int i = 0; i < meshFilters.Count; i++) { if (meshFilters[i] != null && meshFilters[i].gameObject.isStatic) { UnityEngine.Object.DestroyImmediate(meshFilters[i].gameObject); } } var childTr = source.GetComponentsInChildren <Transform>(); for (int i = 0; i < childTr.Length; i++) { if (childTr[i] == null || childTr[i].transform.childCount > 0 || !childTr[i].CompareTag(StringConst.TagDummy)) { continue; } UnityEngine.Object.DestroyImmediate(childTr[i].gameObject); } }
public static void CombineMesh(Transform source, Transform target, bool deleteOriginal, bool splitSectors) { var originalPos = source.transform.position; source.transform.position = Vector3.zero; MeshFilter[] allFilters = source.GetComponentsInChildren <MeshFilter>(); List <MeshFilter> meshFilters = new List <MeshFilter>(); for (int i = 0; i < allFilters.Length; i++) { if (allFilters[i] == null || allFilters[i].transform.parent.GetComponent <LODGroup>() != null || !allFilters[i].gameObject.isStatic) { continue; } meshFilters.Add(allFilters[i]); } Dictionary <Point3, List <MeshCombiner> > sectorMeshCombines = new Dictionary <Point3, List <MeshCombiner> >(); List <MeshCombiner> meshCombines = null; MeshCombiner current = null; if (!splitSectors) { meshCombines = new List <MeshCombiner>(); current = new MeshCombiner(); meshCombines.Add(current); } int errorCnt = 0; for (int i = 0; i < meshFilters.Count; i++) { var meshFilter = meshFilters[i]; MeshRenderer meshRenderer = meshFilter.GetComponent <MeshRenderer>(); if (meshRenderer == null) { continue; } meshRenderer.enabled = !deleteOriginal; if (splitSectors) { var secPos = Game.WorldToSector(meshFilter.transform.position); if (!sectorMeshCombines.TryGetValue(secPos, out meshCombines)) { meshCombines = new List <MeshCombiner>(); sectorMeshCombines.Add(secPos, meshCombines); current = new MeshCombiner(); meshCombines.Add(current); } else { current = meshCombines.LastElement(); } } var mesh = meshFilter.sharedMesh; //var mesh = Application.isPlaying ? meshFilter.mesh : meshFilter.sharedMesh; if (mesh.GetInstanceID() < 0) //is already combined { continue; } for (int m = 0; m < mesh.subMeshCount; m++) { var matList = meshRenderer.sharedMaterials; //var matList = Application.isPlaying ? meshRenderer.materials : meshRenderer.sharedMaterials; if (m >= matList.Length || m >= mesh.subMeshCount) { if (errorCnt < 50) { errorCnt++; Debug.LogError( string.Format( "MeshCombine: GameObject {0} is missing a material", meshRenderer.name)); } continue; } Material mat = matList[m]; if (!current.CanAdd(mesh.vertexCount)) { current = new MeshCombiner(); meshCombines.Add(current); } current.AddMesh(meshFilter, mat, m); } } Transform createPivot = null; if (splitSectors) { foreach (var combine in sectorMeshCombines) { var created = BuildCombineList(combine.Value, target, deleteOriginal, combine.Key.ToString()); for (int i = 0; i < created.Count; i++) { World.Get <CullingSystem>().Add(combine.Key, created[i]); } createPivot = created[0].transform; } } else { createPivot = BuildCombineList(meshCombines, target, deleteOriginal, source.name)[0].transform; } source.position = originalPos; if (!deleteOriginal || createPivot == null) { return; } var childTr = source.GetComponentsInChildren <Transform>(true); Dictionary <Point3, Dictionary <int, Transform> > colliderDict = new Dictionary <Point3, Dictionary <int, Transform> >(); colliderDict.Add(createPivot.rotation.eulerAngles.toPoint3(), new Dictionary <int, Transform>() { { createPivot.gameObject.layer, createPivot } }); for (int i = 0; i < meshFilters.Count; i++) { if (meshFilters[i] == null) { continue; } if (meshFilters[i].gameObject.isStatic) { DeleteObject(createPivot, meshFilters[i].gameObject, colliderDict); } } for (int i = 0; i < childTr.Length; i++) { if (childTr[i] == null) { continue; } if (childTr[i].transform.childCount > 0 || childTr[i].CompareTag(StringConst.TagCreated) || childTr[i].CompareTag(StringConst.TagDoNotDisable)) { continue; } if (childTr[i].CompareTag(StringConst.TagDeleteObject)) { DeleteObject(createPivot, childTr[i].gameObject, colliderDict); continue; } childTr[i].GetComponents <Component>(_monoList); bool foundScripts = false; for (int j = 0; j < _monoList.Count; j++) { var mono = _monoList[j]; if (mono is Transform) { continue; } foundScripts = true; break; } if (foundScripts) { continue; } DeleteObject(createPivot, childTr[i].gameObject, colliderDict); } }