void CreateMergedLODGroupFromSingleMaterialMeshes() { string path = EditorUtility.SaveFilePanelInProject("Save merged mesh", "", "", "Please enter a file name to save the merged mesh to"); if (path.Length != 0) { if (_lodGroupVegetationMeshCombiner.TargetGameObject == null) { return; } LODGroup lodGroup = _lodGroupVegetationMeshCombiner.TargetGameObject.GetComponentInChildren <LODGroup>(); GameObject sourceObject = _lodGroupVegetationMeshCombiner.TargetGameObject; Vector3 targetPosition = sourceObject.transform.position; Quaternion targetRotation = sourceObject.transform.rotation; Vector3 targetScale = sourceObject.transform.localScale; sourceObject.transform.position = new Vector3(0, 0, 0); sourceObject.transform.rotation = Quaternion.identity; sourceObject.transform.localScale = Vector3.one; if (lodGroup == null) { return; } GameObject mergedLODGroupObject = new GameObject("Merged_" + sourceObject.name); LODGroup newLODGroup = mergedLODGroupObject.AddComponent <LODGroup>(); List <CombineInstance> combineInstanceList = new List <CombineInstance>(); LOD[] lods = lodGroup.GetLODs(); // ReSharper disable once InconsistentNaming LOD[] newLODs = lodGroup.GetLODs(); for (int i = 0; i <= lods.Length - 1; i++) { combineInstanceList.Clear(); LOD lod = lods[i]; if (lod.renderers.Length > 0) { GameObject lodObject = new GameObject(sourceObject.name + "_LOD" + i.ToString()); lodObject.transform.SetParent(mergedLODGroupObject.transform); MeshRenderer meshRenderer = lodObject.AddComponent <MeshRenderer>(); MeshFilter meshFilter = lodObject.AddComponent <MeshFilter>(); Renderer[] newRenderers = new Renderer[1]; newRenderers[0] = meshRenderer; newLODs[i].renderers = newRenderers; List <Material> materialList = new List <Material>(); for (int j = 0; j <= lod.renderers.Length - 1; j++) { MeshFilter tempMeshFilter = lod.renderers[j].gameObject.GetComponent <MeshFilter>(); if (!tempMeshFilter) { continue; } CombineInstance combineInstance = new CombineInstance { mesh = tempMeshFilter.sharedMesh, transform = meshFilter.transform.localToWorldMatrix }; combineInstanceList.Add(combineInstance); materialList.Add(lod.renderers[j].sharedMaterial); } Mesh mesh = new Mesh(); Material[] materials = materialList.ToArray(); mesh.CombineMeshes(combineInstanceList.ToArray(), false, true); if (_lodGroupVegetationMeshCombiner.MergeSubmeshesWitEquialMaterial) { SubmeshCombiner submeshCombiner = new SubmeshCombiner(); for (int j = 0; j <= mesh.subMeshCount - 1; j++) { submeshCombiner.AddSubmesh(mesh.GetIndices(j), materials[j]); } submeshCombiner.UpdateMesh(mesh); materials = submeshCombiner.GetMaterials(); } meshFilter.sharedMesh = mesh; AssetDatabase.CreateAsset(meshFilter.sharedMesh, path + "_LOD" + i.ToString() + ".asset"); meshRenderer.materials = materials; } } newLODGroup.SetLODs(newLODs); sourceObject.transform.position = targetPosition; sourceObject.transform.rotation = targetRotation; sourceObject.transform.localScale = targetScale; } }
public static GameObject CombineMeshes(GameObject sourceGameObject, bool mergeSubmeshesWitEquialMaterial) { MeshFilter[] meshFilters = sourceGameObject.GetComponentsInChildren <MeshFilter>(); MeshRenderer[] meshRenderers = sourceGameObject.GetComponentsInChildren <MeshRenderer>(); Vector3 targetPosition = sourceGameObject.transform.position; Quaternion targetRotation = sourceGameObject.transform.rotation; Vector3 targetScale = sourceGameObject.transform.localScale; sourceGameObject.transform.position = new Vector3(0, 0, 0); sourceGameObject.transform.rotation = Quaternion.identity; sourceGameObject.transform.localScale = Vector3.one; CombineInstance[] combine = new CombineInstance[meshFilters.Length]; int i = 0; while (i < meshFilters.Length) { combine[i].mesh = meshFilters[i].sharedMesh; combine[i].transform = meshFilters[i].transform.localToWorldMatrix; i++; } GameObject mergedMesh = new GameObject(sourceGameObject.name + "_Merged"); mergedMesh.transform.position = new Vector3(0, 0, 0); mergedMesh.transform.rotation = Quaternion.identity; mergedMesh.transform.localScale = Vector3.one; MeshFilter meshFilter = mergedMesh.AddComponent <MeshFilter>(); meshFilter.mesh = new Mesh(); meshFilter.sharedMesh.CombineMeshes(combine, false, true); MeshRenderer meshRenderer = mergedMesh.AddComponent <MeshRenderer>(); List <Material> materialList = new List <Material>(); for (int j = 0; j <= meshRenderers.Length - 1; j++) { materialList.AddRange(meshRenderers[j].sharedMaterials); } Material[] materials = materialList.ToArray(); meshRenderer.sharedMaterials = materials; if (mergeSubmeshesWitEquialMaterial) { SubmeshCombiner submeshCombiner = new SubmeshCombiner(); for (int j = 0; j <= meshFilter.sharedMesh.subMeshCount - 1; j++) { submeshCombiner.AddSubmesh(meshFilter.sharedMesh.GetIndices(j), materials[j]); } submeshCombiner.UpdateMesh(meshFilter.sharedMesh); meshRenderer.sharedMaterials = submeshCombiner.GetMaterials(); } sourceGameObject.transform.position = targetPosition; sourceGameObject.transform.rotation = targetRotation; sourceGameObject.transform.localScale = targetScale; mergedMesh.transform.position = targetPosition; mergedMesh.transform.rotation = targetRotation; mergedMesh.transform.localScale = targetScale; return(mergedMesh); }
void CreateMergedLODGroup() { string path = EditorUtility.SaveFilePanelInProject("Save merged mesh", "", "", "Please enter a file name to save the merged mesh to"); if (path.Length != 0) { if (_lodGroupVegetationMeshCombiner.TargetGameObject == null) { return; } LODGroup lodGroup = _lodGroupVegetationMeshCombiner.TargetGameObject.GetComponentInChildren <LODGroup>(); GameObject sourceObject = _lodGroupVegetationMeshCombiner.TargetGameObject; Vector3 targetPosition = sourceObject.transform.position; Quaternion targetRotation = sourceObject.transform.rotation; Vector3 targetScale = sourceObject.transform.localScale; sourceObject.transform.position = new Vector3(0, 0, 0); sourceObject.transform.rotation = Quaternion.identity; sourceObject.transform.localScale = Vector3.one; if (lodGroup == null) { return; } GameObject mergedLODGroupObject = new GameObject("Merged_" + sourceObject.name); LODGroup newLODGroup = mergedLODGroupObject.AddComponent <LODGroup>(); LOD[] lods = lodGroup.GetLODs(); // ReSharper disable once InconsistentNaming LOD[] newLODs = lodGroup.GetLODs(); for (int i = 0; i <= lods.Length - 1; i++) { LOD lod = lods[i]; if (lod.renderers.Length > 0) { GameObject lodObject = new GameObject(sourceObject.name + "_LOD" + i.ToString()); lodObject.transform.SetParent(mergedLODGroupObject.transform); MeshRenderer meshRenderer = lodObject.AddComponent <MeshRenderer>(); MeshFilter meshFilter = lodObject.AddComponent <MeshFilter>(); Renderer renderer = lod.renderers[0]; MeshFilter tempMeshFilter = lod.renderers[0].gameObject.GetComponent <MeshFilter>(); Renderer[] newRenderers = new Renderer[1]; newRenderers[0] = meshRenderer; newLODs[i].renderers = newRenderers; newLODs[i].screenRelativeTransitionHeight = (float)1 / (i + 1); Mesh mesh = Instantiate(tempMeshFilter.sharedMesh); Material[] materials = renderer.sharedMaterials; SubmeshCombiner submeshCombiner = new SubmeshCombiner(); for (int j = 0; j <= mesh.subMeshCount - 1; j++) { submeshCombiner.AddSubmesh(mesh.GetIndices(j), materials[j]); } submeshCombiner.UpdateMesh(mesh); materials = submeshCombiner.GetMaterials(); meshFilter.sharedMesh = mesh; AssetDatabase.CreateAsset(meshFilter.sharedMesh, path + "_LOD" + i.ToString() + ".asset"); meshRenderer.materials = materials; } } newLODGroup.SetLODs(newLODs); sourceObject.transform.position = targetPosition; sourceObject.transform.rotation = targetRotation; sourceObject.transform.localScale = targetScale; } }