public void OneTextureMaterialOneMesh() { dynamic batcherOptions = CreateSimpleBatcherOptions(); GameObject hlodGameObject = new GameObject(); HLOD hlodComponent = hlodGameObject.AddComponent <HLOD>(); var obj1 = GameObject.Instantiate(m_mesh1material1T); obj1.transform.SetParent(hlodComponent.transform); obj1.transform.position = new Vector3(0.0f, 0.0f, 0.0f); var obj2 = GameObject.Instantiate(m_mesh1material1T); obj2.transform.SetParent(hlodComponent.transform); obj2.transform.position = new Vector3(1.0f, 0.0f, 0.0f); using (var buildInfo = CreateBuildInfo(hlodComponent)) using (SimpleBatcher batcher = new SimpleBatcher(batcherOptions)) { batcher.Batch(hlodGameObject.transform.position, buildInfo, null); Assert.AreEqual(buildInfo.Count, 1); Assert.AreEqual(buildInfo[0].WorkingObjects.Count, 1); } }
public void Setup() { //1개의 매터리얼 1개의 메시를 이용하여 테스트 //1개의 매터리얼 2개의 메시를 이용 //2개의 매터리얼 2개의 메시를 이용 //2개의 매터리얼 3개의 메시를 이용 m_mesh1material1 = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD0_2.prefab"); m_mesh2material1 = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD1.prefab"); m_mesh2material2 = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD1_2.prefab"); m_mesh3material2 = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD2.prefab"); m_mesh1material1T = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD0T_2.prefab"); m_mesh2material1T = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD1T.prefab"); m_mesh2material2T = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD1T_2.prefab"); m_mesh3material2T = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD2T.prefab"); m_hlodGameObject = new GameObject(); m_hlodComponent = m_hlodGameObject.AddComponent <HLOD>(); m_buildInfoFunc = typeof(HLODCreator).GetMethod("CreateBuildInfo", BindingFlags.Static | BindingFlags.NonPublic); var types = BatcherTypes.GetTypes(); for (int i = 0; i < types.Length; ++i) { if (types[i].Name == "MaterialPreservingBatcher") { m_batcherType = types[i]; } } }
public static void CreateBuildingHLOD() { if (PrefabStageUtility.GetCurrentPrefabStage() == null || PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot == null) { Debug.LogWarning("Setup HLOD can only be used while prefab editing."); return; } var parent = PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot.transform; if (parent.GetComponent <LODGroup>() != null || parent.GetComponent <HLOD>() != null) { Debug.LogWarning("HLOD is already setup on this hierarchy"); return; } EditorSceneManager.MarkSceneDirty(parent.gameObject.scene); var lowLOD = CreateLowLod(); var highLOD = new GameObject("High LOD").transform; while (parent.childCount != 0) { parent.GetChild(0).SetParent(highLOD, false); } lowLOD.SetParent(parent, false); highLOD.SetParent(parent, false); parent.gameObject.AddComponent(typeof(HLOD)); var hlod = parent.GetComponent <HLOD>(); Transform[] transforms = { highLOD, lowLOD }; hlod.LODParentTransforms = transforms; var lodgroup = parent.GetComponent <LODGroup>(); var lods = lodgroup.GetLODs(); lods[0].screenRelativeTransitionHeight = 0.3F; lods[1].screenRelativeTransitionHeight = 0.02F; ArrayUtility.RemoveAt(ref lods, 2); lodgroup.SetLODs(lods); UpdateBounds(hlod); var generatedMeshes = new List <Mesh>(); GenerateCombinedMesh(hlod, highLOD, lowLOD, 1, generatedMeshes); WriteMeshAsset(generatedMeshes); HLOD.InvalidateHLODCache(); }
private DisposableList <HLODBuildInfo> CreateBuildInfo(HLOD hlod) { MethodInfo buildInfoFunc = typeof(HLODCreator).GetMethod("CreateBuildInfo", BindingFlags.Static | BindingFlags.NonPublic); List <GameObject> hlodTargets = ObjectUtils.HLODTargets(hlod.gameObject); ISpaceSplitter spliter = new QuadTreeSpaceSplitter(0.0f); SpaceNode rootNode = spliter.CreateSpaceTree(hlod.GetBounds(), 5.0f, hlod.transform.position, hlodTargets, null); return((DisposableList <HLODBuildInfo>)buildInfoFunc.Invoke(null, new object[] { rootNode, 0.0f })); }
public static void GenerateCombinedMesh() { if (PrefabStageUtility.GetCurrentPrefabStage() == null || PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot == null) { Debug.LogWarning("UpdateCombinedMesh can only be used while prefab editing."); return; } var root = PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot; var hlod = root.GetComponent <HLOD>(); if (hlod == null) { Debug.LogWarning("UpdateCombinedMesh requires a correctly configured HLOD setup"); return; } EditorSceneManager.MarkSceneDirty(root.gameObject.scene); var hlodTransforms = hlod.LODParentTransforms; var lodCount = hlod.GetComponent <LODGroup>().lodCount; while (lodCount < hlodTransforms.Length) { if (hlodTransforms[hlodTransforms.Length - 1]) { Object.DestroyImmediate(hlodTransforms[hlodTransforms.Length - 1].gameObject); } ArrayUtility.RemoveAt(ref hlodTransforms, hlodTransforms.Length - 1); } System.Array.Resize(ref hlodTransforms, lodCount); var generatedMeshes = new List <Mesh>(); for (int i = 1; i < lodCount; i++) { if (hlodTransforms[i] == null) { hlodTransforms[i] = CreateLowLod(); hlodTransforms[i].SetParent(root.transform, false); } GenerateCombinedMesh(hlod, hlod.LODParentTransforms[0], hlodTransforms[i], i, generatedMeshes); } hlod.LODParentTransforms = hlodTransforms; WriteMeshAsset(generatedMeshes); HLOD.InvalidateHLODCache(); }
protected static void OnGUIBase(HLOD hlod) { EditorGUI.indentLevel += 1; hlod.SimplifyPolygonRatio = EditorGUILayout.Slider("Polygon Ratio", hlod.SimplifyPolygonRatio, 0.0f, 1.0f); EditorGUILayout.LabelField("Triangle Range"); EditorGUI.indentLevel += 1; hlod.SimplifyMinPolygonCount = EditorGUILayout.IntSlider("Min", hlod.SimplifyMinPolygonCount, 10, 100); hlod.SimplifyMaxPolygonCount = EditorGUILayout.IntSlider("Max", hlod.SimplifyMaxPolygonCount, 10, 5000); EditorGUI.indentLevel -= 1; EditorGUI.indentLevel -= 1; }
public void Setup() { GameObject prefab = AssetDatabase.LoadAssetAtPath <GameObject>(m_prefabName); m_hlodGameObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab); PrefabUtility.UnpackPrefabInstance(m_hlodGameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction); m_hlod = m_hlodGameObject.GetComponentInChildren <HLOD>(); var coroutine = CoroutineRunner.RunCoroutine(HLODCreator.Create(m_hlod)); while (coroutine.MoveNext()) { //Wait until coroutine is finished } }
public void Setup() { Scene scene = EditorSceneManager.OpenScene("Assets/TestAssets/EditModeTestScene.unity"); GameObject[] gameObjects = scene.GetRootGameObjects(); mHlodGameObject = gameObjects[0].transform.Find("HLOD").gameObject; hlod = mHlodGameObject.GetComponent <HLOD>() as HLOD; var coroutine = CoroutineRunner.RunCoroutine(HLODCreator.Create(hlod)); while (coroutine.MoveNext()) { //Wait until coroutine is finished } }
public static void UpdateBounds(HLOD hlod) { var renderers = hlod.GetComponentsInChildren <Renderer>(); Bounds bounds = renderers[0].bounds; for (int i = 0; i != renderers.Length; i++) { bounds.Encapsulate(renderers[i].bounds); } var lodgroup = hlod.GetComponent <LODGroup>(); lodgroup.size = bounds.size.magnitude; lodgroup.localReferencePoint = lodgroup.transform.InverseTransformPoint(bounds.center); }
public IEnumerator Simplify(HLOD hlod) { yield break; }
public NotUseSimplifier(HLOD hlod) { }
public NotSupportStreaming(HLOD hlod) { m_hlod = hlod; }
public static void OnGUI(HLOD hlod) { OnGUIBase(hlod); }
public UnityMeshSimplifier(HLOD hlod) : base(hlod) { }
public SimplifierBase(HLOD hlod) { m_hlod = hlod; }
public void PackingTextureTest() { MethodInfo packingTextureMethod = typeof(SimpleBatcher).GetMethod("PackingTexture", BindingFlags.Instance | BindingFlags.NonPublic); dynamic batcherOptions = CreateSimpleBatcherOptions(); GameObject hlodGameObject = new GameObject(); HLOD hlodComponent = hlodGameObject.AddComponent <HLOD>(); var obj1 = GameObject.Instantiate(m_material1T); obj1.transform.SetParent(hlodComponent.transform); obj1.transform.position = new Vector3(0.0f, 0.0f, 0.0f); var obj2 = GameObject.Instantiate(m_material2T); obj2.transform.SetParent(hlodComponent.transform); obj2.transform.position = new Vector3(1.0f, 0.0f, 0.0f); var obj3 = GameObject.Instantiate(m_material3T); obj3.transform.SetParent(hlodComponent.transform); obj3.transform.position = new Vector3(2.0f, 0.0f, 0.0f); var obj4 = GameObject.Instantiate(m_material4T); obj4.transform.SetParent(hlodComponent.transform); obj4.transform.position = new Vector3(3.0f, 0.0f, 0.0f); batcherOptions.PackTextureSize = 256; batcherOptions.LimitTextureSize = 128; using (var buildInfo = CreateBuildInfo(hlodComponent)) using (TexturePacker packer = new TexturePacker()) using (SimpleBatcher batcher = new SimpleBatcher(batcherOptions)) { packingTextureMethod.Invoke(batcher, new object[] { packer, buildInfo, batcherOptions, null }); Assert.AreEqual(packer.GetAllAtlases().Length, 1); var atlas = packer.GetAllAtlases()[0]; Assert.AreEqual(atlas.Objects[0], buildInfo[0]); Assert.AreEqual(atlas.Textures.Count, 1); var texture = atlas.Textures[0]; Assert.AreEqual(256, texture.Width); Assert.AreEqual(256, texture.Height); Assert.AreEqual(new Rect(0.0f, 0.0f, 0.5f, 0.5f), atlas.GetUV(buildInfo[0].WorkingObjects[0].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.5f, 0.0f, 0.5f, 0.5f), atlas.GetUV(buildInfo[0].WorkingObjects[1].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.0f, 0.5f, 0.5f, 0.5f), atlas.GetUV(buildInfo[0].WorkingObjects[2].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.5f, 0.5f, 0.5f, 0.5f), atlas.GetUV(buildInfo[0].WorkingObjects[3].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Color(1.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(0, 0)); Assert.AreEqual(new Color(0.0f, 0.0f, 1.0f, 1.0f), texture.GetPixel(255, 0)); Assert.AreEqual(new Color(0.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(0, 255)); Assert.AreEqual(new Color(1.0f, 0.0f, 0.0f, 1.0f), texture.GetPixel(255, 255)); Assert.AreEqual(new Color(1.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(127, 127)); Assert.AreEqual(new Color(0.0f, 0.0f, 1.0f, 1.0f), texture.GetPixel(128, 127)); Assert.AreEqual(new Color(0.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(127, 128)); Assert.AreEqual(new Color(1.0f, 0.0f, 0.0f, 1.0f), texture.GetPixel(128, 128)); } batcherOptions.PackTextureSize = 128; batcherOptions.LimitTextureSize = 128; using (var buildInfo = CreateBuildInfo(hlodComponent)) using (TexturePacker packer = new TexturePacker()) using (SimpleBatcher batcher = new SimpleBatcher(batcherOptions)) { packingTextureMethod.Invoke(batcher, new object[] { packer, buildInfo, batcherOptions, null }); Assert.AreEqual(packer.GetAllAtlases().Length, 1); var atlas = packer.GetAllAtlases()[0]; Assert.AreEqual(atlas.Objects[0], buildInfo[0]); Assert.AreEqual(atlas.Textures.Count, 1); var texture = atlas.Textures[0]; Assert.AreEqual(128, texture.Width); Assert.AreEqual(128, texture.Height); Assert.AreEqual(new Rect(0.0f, 0.0f, 0.5f, 0.5f), atlas.GetUV(buildInfo[0].WorkingObjects[0].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.5f, 0.0f, 0.5f, 0.5f), atlas.GetUV(buildInfo[0].WorkingObjects[1].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.0f, 0.5f, 0.5f, 0.5f), atlas.GetUV(buildInfo[0].WorkingObjects[2].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.5f, 0.5f, 0.5f, 0.5f), atlas.GetUV(buildInfo[0].WorkingObjects[3].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Color(1.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(0, 0)); Assert.AreEqual(new Color(0.0f, 0.0f, 1.0f, 1.0f), texture.GetPixel(127, 0)); Assert.AreEqual(new Color(0.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(0, 127)); Assert.AreEqual(new Color(1.0f, 0.0f, 0.0f, 1.0f), texture.GetPixel(127, 127)); Assert.AreEqual(new Color(1.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(63, 63)); Assert.AreEqual(new Color(0.0f, 0.0f, 1.0f, 1.0f), texture.GetPixel(64, 63)); Assert.AreEqual(new Color(0.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(63, 64)); Assert.AreEqual(new Color(1.0f, 0.0f, 0.0f, 1.0f), texture.GetPixel(64, 64)); } batcherOptions.PackTextureSize = 512; batcherOptions.LimitTextureSize = 128; using (var buildInfo = CreateBuildInfo(hlodComponent)) using (TexturePacker packer = new TexturePacker()) using (SimpleBatcher batcher = new SimpleBatcher(batcherOptions)) { packingTextureMethod.Invoke(batcher, new object[] { packer, buildInfo, batcherOptions, null }); Assert.AreEqual(packer.GetAllAtlases().Length, 1); var atlas = packer.GetAllAtlases()[0]; Assert.AreEqual(atlas.Objects[0], buildInfo[0]); Assert.AreEqual(atlas.Textures.Count, 1); var texture = atlas.Textures[0]; Assert.AreEqual(512, texture.Width); Assert.AreEqual(512, texture.Height); Assert.AreEqual(new Rect(0.0f, 0.0f, 0.25f, 0.25f), atlas.GetUV(buildInfo[0].WorkingObjects[0].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.5f, 0.0f, 0.25f, 0.25f), atlas.GetUV(buildInfo[0].WorkingObjects[1].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.0f, 0.5f, 0.25f, 0.25f), atlas.GetUV(buildInfo[0].WorkingObjects[2].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Rect(0.5f, 0.5f, 0.25f, 0.25f), atlas.GetUV(buildInfo[0].WorkingObjects[3].Materials[0].GetTexture("_MainTex").GetGUID())); Assert.AreEqual(new Color(1.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(0, 0)); Assert.AreEqual(new Color(1.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(127, 127)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(127, 128)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(128, 127)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(255, 255)); Assert.AreEqual(new Color(0.0f, 0.0f, 1.0f, 1.0f), texture.GetPixel(256, 0)); Assert.AreEqual(new Color(0.0f, 0.0f, 1.0f, 1.0f), texture.GetPixel(383, 127)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(384, 127)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(383, 128)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(511, 255)); Assert.AreEqual(new Color(0.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(0, 256)); Assert.AreEqual(new Color(0.0f, 1.0f, 0.0f, 1.0f), texture.GetPixel(127, 383)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(128, 383)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(127, 384)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(255, 511)); Assert.AreEqual(new Color(1.0f, 0.0f, 0.0f, 1.0f), texture.GetPixel(256, 256)); Assert.AreEqual(new Color(1.0f, 0.0f, 0.0f, 1.0f), texture.GetPixel(383, 383)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(384, 383)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(383, 384)); Assert.AreEqual(new Color(0.0f, 0.0f, 0.0f, 0.0f), texture.GetPixel(511, 511)); } }
public void Setup() { m_prefab = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber.prefab"); m_prefabMesh = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/TestAssets/Prefabs/RinNumber_LOD3.prefab"); m_buildInfoFunc = typeof(HLODCreator).GetMethod("CreateBuildInfo", BindingFlags.Static | BindingFlags.NonPublic); m_hlodRootGameObject = new GameObject(); m_hlodComponent = m_hlodRootGameObject.AddComponent <HLOD>(); var obj1 = GameObject.Instantiate(m_prefab); obj1.transform.SetParent(m_hlodRootGameObject.transform); obj1.transform.position = new Vector3(0.0f, 0.0f, 0.0f); m_includeObjects.Add(obj1); var obj2 = GameObject.Instantiate(m_prefab); obj2.transform.SetParent(m_hlodRootGameObject.transform); obj2.transform.position = new Vector3(10.0f, 0.0f, -10.0f); m_includeObjects.Add(obj2); var obj3 = GameObject.Instantiate(m_prefab); obj3.transform.SetParent(m_hlodRootGameObject.transform); obj3.transform.position = new Vector3(-10.0f, 0.0f, -10.0f); m_includeObjects.Add(obj3); var obj4 = GameObject.Instantiate(m_prefab); obj4.transform.SetParent(m_hlodRootGameObject.transform); obj4.transform.position = new Vector3(10.0f, 0.0f, 10.0f); m_includeObjects.Add(obj4); var obj5 = GameObject.Instantiate(m_prefab); obj5.transform.SetParent(m_hlodRootGameObject.transform); obj5.transform.position = new Vector3(-10.0f, 0.0f, 10.0f); m_includeObjects.Add(obj5); var obj6 = GameObject.Instantiate(m_prefabMesh); obj6.transform.SetParent(m_hlodRootGameObject.transform); obj6.transform.position = new Vector3(-5.0f, 0.0f, -5.0f); obj6.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); m_includeObjects.Add(obj6); var obj7 = GameObject.Instantiate(m_prefabMesh); obj7.transform.SetParent(m_hlodRootGameObject.transform); obj7.transform.position = new Vector3(-5.0f, 0.0f, 5.0f); obj7.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f); m_includeObjects.Add(obj7); var obj8 = GameObject.Instantiate(m_prefabMesh); obj8.transform.SetParent(m_hlodRootGameObject.transform); obj8.transform.position = new Vector3(5.0f, 0.0f, -5.0f); obj8.transform.localScale = new Vector3(2.0f, 2.0f, 2.0f); m_includeObjects.Add(obj8); var obj9 = GameObject.Instantiate(m_prefabMesh); obj9.transform.SetParent(m_hlodRootGameObject.transform); obj9.transform.position = new Vector3(5.0f, 0.0f, 5.0f); obj9.transform.localScale = new Vector3(5.0f, 5.0f, 5.0f); m_includeObjects.Add(obj9); //this should be exclude. var obj10 = new GameObject(); obj10.transform.SetParent(m_hlodRootGameObject.transform); obj10.transform.position = new Vector3(40.0f, 0.0f, 40.0f); m_excludeObjects.Add(obj10); var obj11 = new GameObject(); obj11.transform.SetParent(m_hlodRootGameObject.transform); obj11.transform.position = new Vector3(-40.0f, 0.0f, -40.0f); m_excludeObjects.Add(obj11); }
public static void GenerateCombinedMesh(HLOD hlod, Transform sourceLOD, Transform generatedLOD, int lodIndex, List <Mesh> generatedMeshes) { const float fieldOfView = 60.0F; const float distanceBias = 0.0F; var instances = new Dictionary <Material, List <CombineInstance> >(); var lodGroups = sourceLOD.GetComponentsInChildren <LODGroup>(); var hlodSwitchDistance = LODGroupExtensions.CalculateLODSwitchDistance(fieldOfView, hlod.GetComponent <LODGroup>(), lodIndex - 1); foreach (var group in lodGroups) { float cullingDistance = LODGroupExtensions.CalculateLODSwitchDistance(fieldOfView, group, group.lodCount - 1); if (cullingDistance + distanceBias < hlodSwitchDistance) { continue; } var renderers = group.GetLODs()[group.lodCount - 1].renderers; foreach (var renderer in renderers) { var meshRenderer = renderer as MeshRenderer; if (meshRenderer == null) { continue; } var instance = new CombineInstance(); instance.transform = generatedLOD.worldToLocalMatrix * renderer.transform.localToWorldMatrix; var materials = meshRenderer.sharedMaterials; for (int m = 0; m != materials.Length; m++) { if (!instances.ContainsKey(materials[m])) { instances[materials[m]] = new List <CombineInstance>(); } instance.mesh = meshRenderer.GetComponent <MeshFilter>().sharedMesh; instance.subMeshIndex = m; instances[materials[m]].Add(instance); } } } while (generatedLOD.childCount != 0) { Object.DestroyImmediate(generatedLOD.GetChild(0).gameObject); } var generatedRenderers = new List <Renderer>(); foreach (var instance in instances) { var mesh = new Mesh(); mesh.name = "CombinedLowLOD"; mesh.CombineMeshes(instance.Value.ToArray(), true, true, false); var go = new GameObject("CombinedLowLOD", typeof(MeshRenderer), typeof(MeshFilter)); go.GetComponent <MeshFilter>().sharedMesh = mesh; go.GetComponent <MeshRenderer>().sharedMaterial = instance.Key; generatedRenderers.Add(go.GetComponent <MeshRenderer>()); generatedMeshes.Add(mesh); go.transform.SetParent(generatedLOD, false); } var lodGroup = generatedLOD.GetComponent <LODGroup>(); var lods = lodGroup.GetLODs(); lods[0].renderers = generatedRenderers.ToArray(); lodGroup.SetLODs(lods); }