Ejemplo n.º 1
0
        public void OptimizeShader(bool reuseTextures, bool generatePrefabs)
        {
            if (shaderName == "")//unknown shader doesnt need to be optimed
            {
                return;
            }
            int currentAtlasSize = CalculateAproxAtlasSize(reuseTextures); //(reuseTextures) ? aproxAtlasSizeReuseTextures : aproxAtlasSize;

            if ((objects.Count > 1 ||                                      //more than 1 obj or 1 obj with multiple mat
                 (objects.Count == 1 && objects[0] != null && objects[0].ObjHasMoreThanOneMaterial)) &&
                currentAtlasSize < Constants.MaxAtlasSize)                 //check the generated atlas size doesnt exceed max supported texture size

            {
                List <Rect> texturePositions = new List <Rect>(); //creo que puede morir porque el atlasser tiene adentro un rect.
                Node        resultNode       = null;              //nodes for the tree for atlasing


                Atlasser generatedAtlas = new Atlasser(currentAtlasSize, currentAtlasSize);
                int      resizeTimes    = 1;

                TextureReuseManager textureReuseManager = new TextureReuseManager();

                for (int j = objects.Count - 1; j >= 0; j--)  //start from the largest to the shortest textures
                {
                    if (objects[j].ObjHasMoreThanOneMaterial) //before atlassing multiple materials obj, combine it.
                    {
                        objects[j].ProcessAndCombineMaterials();
                    }

                    Vector2 textureToAtlasSize = objects[j].TextureSize;
                    if (reuseTextures)
                    {
                        //if texture is not registered already
                        if (!textureReuseManager.TextureRefExists(objects[j]))
                        {
                            //generate a node
                            resultNode = generatedAtlas.Insert(Mathf.RoundToInt((textureToAtlasSize.x != Constants.NULLV2.x) ? textureToAtlasSize.x : Constants.NullTextureSize),
                                                               Mathf.RoundToInt((textureToAtlasSize.y != Constants.NULLV2.y) ? textureToAtlasSize.y : Constants.NullTextureSize));
                            if (resultNode != null) //save node if fits in atlas
                            {
                                textureReuseManager.AddTextureRef(objects[j], resultNode.NodeRect, j);
                            }
                        }
                    }
                    else
                    {
                        resultNode = generatedAtlas.Insert(Mathf.RoundToInt((textureToAtlasSize.x != Constants.NULLV2.x) ? textureToAtlasSize.x : Constants.NullTextureSize),
                                                           Mathf.RoundToInt((textureToAtlasSize.y != Constants.NULLV2.y) ? textureToAtlasSize.y : Constants.NullTextureSize));
                    }
                    if (resultNode == null)
                    {
                        int resizedAtlasSize = currentAtlasSize + Mathf.RoundToInt((float)currentAtlasSize * Constants.AtlasResizeFactor * resizeTimes);
                        generatedAtlas = new Atlasser(resizedAtlasSize, resizedAtlasSize);
                        j = objects.Count;//Count and not .Count-1 bc at the end of the loop it will be substracted j-- and we want to start from Count-1

                        texturePositions.Clear();
                        textureReuseManager.ClearTextureRefs();
                        resizeTimes++;
                    }
                    else
                    {
                        if (reuseTextures)
                        {
                            texturePositions.Add(textureReuseManager.GetTextureRefPosition(objects[j]));
                        }
                        else
                        {
                            texturePositions.Add(resultNode.NodeRect);//save the texture rectangle
                        }
                    }
                }
                Material atlasMaterial = CreateAtlasMaterialAndTexture(generatedAtlas, shaderName, textureReuseManager);
                OptimizeDrawCalls(ref atlasMaterial,
                                  generatedAtlas.GetAtlasSize().x,
                                  generatedAtlas.GetAtlasSize().y,
                                  texturePositions,
                                  reuseTextures,
                                  textureReuseManager,
                                  generatePrefabs);
                //after the game object has been organized, remove the combined game objects.
                for (int i = 0; i < objects.Count; i++)
                {
                    if (objects[i].ObjWasCombined)
                    {
                        objects[i].ClearCombinedObject();
                    }
                }
            }
        }
        void OnGUI()
        {
            if (NeedToReload())
            {
                ReloadDataStructures();
            }
            selectedMenuOption = GUI.SelectionGrid(new Rect(5, 8, window.position.width - 10, 20), selectedMenuOption, menuOptions, 3);
            switch (selectedMenuOption)
            {
            case 0:
                ObjectsGUI.Instance.DrawGUI(window);
                AdvancedMenuGUI.Instance.ClearConsole();
                menuOptions[0] = "Objects";
                break;

            case 1:
                ShadersGUI.Instance.DrawGUI(window);
                AdvancedMenuGUI.Instance.ClearConsole();
                menuOptions[0] = "Objects(" + ObjSorter.GetTotalSortedObjects() + ")";
                break;

            case 2:
                AdvancedMenuGUI.Instance.DrawGUI(window);
                menuOptions[0] = "Objects(" + ObjSorter.GetTotalSortedObjects() + ")";
                break;

            default:
                Debug.LogError("Unrecognized menu option: " + selectedMenuOption);
                break;
            }

            if (GUI.Button(new Rect(5, window.position.height - 35, window.position.width / 2 - 10, 33), "Clear Atlas"))
            {
                GameObject[] objsInHierarchy = Utils.GetAllObjectsInHierarchy();
                foreach (GameObject obj in objsInHierarchy)
                {
                    if (obj.name.Contains(Constants.OptimizedObjIdentifier))
                    {
                        DestroyImmediate(obj);
                    }
                    else
                    if (obj.GetComponent <MeshRenderer>() != null)
                    {
                        obj.GetComponent <MeshRenderer>().enabled = true;
                    }
                }
                // delete the folder where the atlas reside.
                string folderOfAtlas = EditorApplication.currentScene;
                if (folderOfAtlas == "")                  //scene is not saved yet.
                {
                    folderOfAtlas = Constants.NonSavedSceneFolderName + ".unity";
                    Debug.LogWarning("WARNING: Scene has not been saved, clearing baked objects from NOT_SAVED_SCENE folder");
                }
                folderOfAtlas = folderOfAtlas.Substring(0, folderOfAtlas.Length - 6) + "-Atlas";  //remove the ".unity"
                if (Directory.Exists(folderOfAtlas))
                {
                    FileUtil.DeleteFileOrDirectory(folderOfAtlas);
                    AssetDatabase.Refresh();
                }
            }

            GUI.enabled = CheckEmptyArray();     //if there are no textures deactivate the GUI
            if (GUI.Button(new Rect(window.position.width / 2, window.position.height - 35, window.position.width / 2 - 5, 33), "Bake Atlas"))
            {
                //Remove objects that are already optimized and start over.
                if (AdvancedMenuGUI.Instance.RemoveObjectsBeforeBaking)
                {
                    GameObject[] objsInHierarchy = Utils.GetAllObjectsInHierarchy();
                    foreach (GameObject obj in objsInHierarchy)
                    {
                        if (obj.name.Contains(Constants.OptimizedObjIdentifier))
                        {
                            GameObject.DestroyImmediate(obj);
                        }
                    }
                }

                List <Rect> texturePositions = new List <Rect>();  //creo que esto puede morir porque el atlasser tiene adentro un rect.
                string      progressBarInfo  = "";
                float       pace             = 1 / (float)ObjSorter.GetRecognizableShadersCount();
                float       progress         = pace;

                Node resultNode = null;    //nodes for the tree for atlasing
                for (int shaderIndex = 0; shaderIndex < ObjSorter.GetObjs().Count; shaderIndex++)
                {
                    EditorUtility.DisplayProgressBar("Optimization in progress... " +
                                                     (AdvancedMenuGUI.Instance.CreatePrefabsForObjects ? " Get coffee this will take some time..." : ""), progressBarInfo, progress);
                    progress += pace;

                    texturePositions.Clear();
                    TextureReuseManager textureReuseManager = new TextureReuseManager();

                    string shaderToAtlas = (ObjSorter.GetObjs()[shaderIndex][0] != null && ObjSorter.GetObjs()[shaderIndex][0].IsCorrectlyAssembled) ? ObjSorter.GetObjs()[shaderIndex][0].ShaderName : "";
                    progressBarInfo = "Processing shader " + shaderToAtlas + "...";
                    int atlasSize = ObjSorter.GetAproxAtlasSize(shaderIndex, AdvancedMenuGUI.Instance.ReuseTextures);

                    if (ShaderManager.Instance.ShaderExists(shaderToAtlas) &&
                        (ObjSorter.GetObjs()[shaderIndex].Count > 1 ||
                         (ObjSorter.GetObjs()[shaderIndex].Count == 1 && ObjSorter.GetObjs()[shaderIndex][0] != null && ObjSorter.GetObjs()[shaderIndex][0].ObjHasMoreThanOneMaterial)) && //more than 1 obj or 1obj wth multiple mat
                        atlasSize < Constants.MaxAtlasSize)                                                                                                                                //check the generated atlas size doesnt exceed max supported texture size
                    {
                        generatedAtlas = new Atlasser(atlasSize, atlasSize);
                        int resizeTimes = 1;

                        for (int j = ObjSorter.GetObjs()[shaderIndex].Count - 1; j >= 0; j--)   //start from the largest to the shortest textures
                        //before atlassing multiple materials obj, combine it.
                        {
                            if (ObjSorter.GetObjs()[shaderIndex][j].ObjHasMoreThanOneMaterial)
                            {
                                progressBarInfo = "Combining materials...";
                                ObjSorter.GetObjs()[shaderIndex][j].ProcessAndCombineMaterials();    //mirar esto, aca esta el problema  de multiple materiales y reimportacion
                            }

                            Vector2 textureToAtlasSize = ObjSorter.GetObjs()[shaderIndex][j].TextureSize;
                            if (AdvancedMenuGUI.Instance.ReuseTextures)
                            {
                                //if texture is not registered already
                                if (!textureReuseManager.TextureRefExists(ObjSorter.GetObjs()[shaderIndex][j]))
                                {
                                    //generate a node
                                    resultNode = generatedAtlas.Insert(Mathf.RoundToInt((textureToAtlasSize.x != Constants.NULLV2.x) ? textureToAtlasSize.x : Constants.NullTextureSize),
                                                                       Mathf.RoundToInt((textureToAtlasSize.y != Constants.NULLV2.y) ? textureToAtlasSize.y : Constants.NullTextureSize));
                                    if (resultNode != null)      //save node if fits in atlas
                                    {
                                        textureReuseManager.AddTextureRef(ObjSorter.GetObjs()[shaderIndex][j], resultNode.NodeRect, j);
                                    }
                                }
                            }
                            else
                            {
                                resultNode = generatedAtlas.Insert(Mathf.RoundToInt((textureToAtlasSize.x != Constants.NULLV2.x) ? textureToAtlasSize.x : Constants.NullTextureSize),
                                                                   Mathf.RoundToInt((textureToAtlasSize.y != Constants.NULLV2.y) ? textureToAtlasSize.y : Constants.NullTextureSize));
                            }

                            if (resultNode == null)
                            {
                                int resizedAtlasSize = atlasSize + Mathf.RoundToInt((float)atlasSize * Constants.AtlasResizeFactor * resizeTimes);
                                generatedAtlas = new Atlasser(resizedAtlasSize, resizedAtlasSize);
                                j = ObjSorter.GetObjs()[shaderIndex].Count;    //Count and not .Count-1 bc at the end of the loop it will be substracted j-- and we want to start from Count-1

                                texturePositions.Clear();
                                textureReuseManager.ClearTextureRefs();
                                resizeTimes++;
                            }
                            else
                            {
                                if (AdvancedMenuGUI.Instance.ReuseTextures)
                                {
                                    texturePositions.Add(textureReuseManager.GetTextureRefPosition(ObjSorter.GetObjs()[shaderIndex][j]));
                                }
                                else
                                {
                                    texturePositions.Add(resultNode.NodeRect);    //save the texture rectangle
                                }
                            }
                        }
                        progressBarInfo = "Saving textures to atlas...";
                        Material atlasMaterial = CreateAtlasMaterialAndTexture(shaderToAtlas, shaderIndex, textureReuseManager);
                        progressBarInfo = "Remapping coordinates...";

                        ObjSorter.OptimizeDrawCalls(ref atlasMaterial,
                                                    shaderIndex,
                                                    generatedAtlas.GetAtlasSize().x,
                                                    generatedAtlas.GetAtlasSize().y,
                                                    texturePositions,
                                                    AdvancedMenuGUI.Instance.ReuseTextures,
                                                    textureReuseManager,
                                                    AdvancedMenuGUI.Instance.CreatePrefabsForObjects);
                    }
                }

                //after the game object has been organized, remove the combined game objects.
                for (int shaderIndex = 0; shaderIndex < ObjSorter.GetObjs().Count; shaderIndex++)
                {
                    for (int j = ObjSorter.GetObjs()[shaderIndex].Count - 1; j >= 0; j--)
                    {
                        if (ObjSorter.GetObjs()[shaderIndex][j].ObjWasCombined)
                        {
                            ObjSorter.GetObjs()[shaderIndex][j].ClearCombinedObject();
                        }
                    }
                }
                EditorUtility.ClearProgressBar();
                AssetDatabase.Refresh();    //reimport the created atlases so they get displayed in the editor.
            }
        }
Ejemplo n.º 3
0
        private void OptimizeDrawCalls(ref Material atlasMaterial, float atlasWidth, float atlasHeight, List <Rect> texturePos, bool reuseTextures, TextureReuseManager texReuseMgr, bool generatePrefabsForObjects)
        {
            GameObject trash = new GameObject("Trash");//stores unnecesary objects that might be cloned and are children of objects

            // // // when generating prefabs // // //
            string folderToSavePrefabs = EditorApplication.currentScene;

            if (generatePrefabsForObjects)
            {
                if (folderToSavePrefabs == "") //scene is not saved yet.
                {
                    folderToSavePrefabs = Constants.NonSavedSceneFolderName + ".unity";
                }
                folderToSavePrefabs  = folderToSavePrefabs.Substring(0, folderToSavePrefabs.Length - 6) + "-Atlas";//remove the ".unity"
                folderToSavePrefabs += Path.DirectorySeparatorChar + "Prefabs";
                if (!Directory.Exists(folderToSavePrefabs))
                {
                    Directory.CreateDirectory(folderToSavePrefabs);
                    AssetDatabase.Refresh();
                }
            }
            ///////////////////////////////////////////

            for (int i = 0; i < objects.Count; i++)
            {
                string optimizedObjID = objects[i].GameObj.name + Constants.OptimizedObjIdentifier;

                objects[i].GameObj.GetComponent <MeshRenderer>().enabled = true;//activate renderers for instantiating
                GameObject instance = GameObject.Instantiate(objects[i].GameObj,
                                                             objects[i].GameObj.transform.position,
                                                             objects[i].GameObj.transform.rotation) as GameObject;
                Undo.RegisterCreatedObjectUndo(instance, "CreateObj" + optimizedObjID);

                //remove children of the created instance.
                Transform[] children = instance.GetComponentsInChildren <Transform>();
                for (int j = 0; j < children.Length; j++)
                {
                    children[j].transform.parent = trash.transform;
                }

                instance.transform.parent     = objects[i].GameObj.transform.parent;
                instance.transform.localScale = objects[i].GameObj.transform.localScale;
                instance.GetComponent <Renderer>().sharedMaterial = atlasMaterial;
                instance.name = optimizedObjID;

                instance.GetComponent <MeshFilter>().sharedMesh = Utils.CopyMesh(objects[i].GameObj.GetComponent <MeshFilter>().sharedMesh);

                //Remap uvs
                Mesh      remappedMesh = instance.GetComponent <MeshFilter>().sharedMesh;
                Vector2[] remappedUVs  = instance.GetComponent <MeshFilter>().sharedMesh.uv;
                for (int j = 0; j < remappedUVs.Length; j++)
                {
                    if (reuseTextures)
                    {
                        remappedUVs[j] = Utils.ReMapUV(remappedUVs[j],
                                                       atlasWidth,
                                                       atlasHeight,
                                                       texReuseMgr.GetTextureRefPosition(objects[i]),
                                                       instance.name);
                    }
                    else
                    {
                        remappedUVs[j] = Utils.ReMapUV(remappedUVs[j], atlasWidth, atlasHeight, texturePos[i], instance.name);
                    }
                }
                remappedMesh.uv = remappedUVs;

                instance.GetComponent <MeshFilter>().sharedMesh = remappedMesh;

                Undo.RecordObject(objects[i].GameObj.GetComponent <MeshRenderer>(), "Active Obj");

                //if the gameObject has multiple materials, search for the original one (the uncombined) in order to deactivate it
                if (objects[i].ObjWasCombined)
                {
                    objects[i].UncombinedObject.GetComponent <MeshRenderer>().enabled = false;
                }
                else
                {
                    objects[i].GameObj.GetComponent <MeshRenderer>().enabled = false;
                }

                if (generatePrefabsForObjects)
                {
                    string prefabName = Utils.GetValiName(instance.name) + " " + instance.GetInstanceID();
                    string assetPath  = folderToSavePrefabs + Path.DirectorySeparatorChar + prefabName;
                    AssetDatabase.CreateAsset(instance.GetComponent <MeshFilter>().sharedMesh, assetPath + ".asset");
                    PrefabUtility.CreatePrefab(assetPath + ".prefab", instance, ReplacePrefabOptions.ConnectToPrefab);
                }
            }
            GameObject.DestroyImmediate(trash);
        }
Ejemplo n.º 4
0
        //Optimizable object slice is a slice of the optimizableObjects in case they dont fit in a simple atlas
        private void OptimizeDrawCalls(List <OptimizableObject> objectsToOptimizeSlice, ref Material atlasMaterial, float atlasWidth, float atlasHeight, List <Rect> texturePos, bool reuseTextures, TextureReuseManager texReuseMgr, bool generatePrefabsForObjects)
        {
            GameObject trash = new GameObject("Trash");//stores unnecesary objects that might be cloned and are children of objects

            for (int i = 0; i < objectsToOptimizeSlice.Count; i++)
            {
                string optimizedObjStrID = objectsToOptimizeSlice[i].GameObj.name + Constants.OptimizedObjIdentifier;
                if (objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer)
                {
                    objectsToOptimizeSlice[i].GameObj.GetComponent <SkinnedMeshRenderer>().enabled = true;//activate renderers for instantiating
                }
                else
                {
                    objectsToOptimizeSlice[i].GameObj.GetComponent <MeshRenderer>().enabled = true;
                }

                GameObject instance = GameObject.Instantiate(objectsToOptimizeSlice[i].GameObj,
                                                             objectsToOptimizeSlice[i].GameObj.transform.position,
                                                             objectsToOptimizeSlice[i].GameObj.transform.rotation) as GameObject;
                Undo.RegisterCreatedObjectUndo(instance, "CreateObj" + optimizedObjStrID);

                //remove children of the created instance.
                Transform[] children = instance.GetComponentsInChildren <Transform>();
                for (int j = 0; j < children.Length; j++)
                {
                    children[j].transform.parent = trash.transform;
                }

                instance.transform.parent     = objectsToOptimizeSlice[i].GameObj.transform.parent;
                instance.transform.localScale = objectsToOptimizeSlice[i].GameObj.transform.localScale;
                if (objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer)
                {
                    instance.GetComponent <SkinnedMeshRenderer>().sharedMaterial = atlasMaterial;
                }
                else
                {
                    instance.GetComponent <MeshRenderer>().sharedMaterial = atlasMaterial;
                }

                instance.name = optimizedObjStrID;
                if (objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer)
                {
                    instance.GetComponent <SkinnedMeshRenderer>().sharedMesh = Utils.CopyMesh(objectsToOptimizeSlice[i].GameObj.GetComponent <SkinnedMeshRenderer>().sharedMesh);
                }
                else
                {
                    instance.GetComponent <MeshFilter>().sharedMesh = Utils.CopyMesh(objectsToOptimizeSlice[i].GameObj.GetComponent <MeshFilter>().sharedMesh);
                }

                // ************************************ Remap uvs ***************************************** //
                Mesh      remappedMesh  = objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer ? instance.GetComponent <SkinnedMeshRenderer>().sharedMesh : instance.GetComponent <MeshFilter>().sharedMesh;
                Vector2[] remappedUVs   = remappedMesh.uv;//objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer ? instance.GetComponent<SkinnedMeshRenderer>().sharedMesh.uv : instance.GetComponent<MeshFilter>().sharedMesh.uv;
                Vector2[] remappedUVs2  = remappedMesh.uv2;
                Vector2[] remappedUVs3  = remappedMesh.uv3;
                Vector2[] remappedUVs4  = remappedMesh.uv4;
                bool      hasUv2Channel = remappedUVs2.Length > 0;
                bool      hasUv3Channel = remappedUVs3.Length > 0;
                bool      hasUv4Channel = remappedUVs4.Length > 0;

                bool generatedTexture = objectsToOptimizeSlice[i].MainTexture == null;

                for (int j = 0; j < remappedUVs.Length; j++)
                {
                    if (reuseTextures)
                    {
                        if (SettingsMenuGUI.Instance.ModifyMainUV)
                        {
                            remappedUVs[j] = Utils.ReMapUV(remappedUVs[j],
                                                           atlasWidth,
                                                           atlasHeight,
                                                           texReuseMgr.GetTextureRefPosition(objectsToOptimizeSlice[i]),
                                                           instance.name, generatedTexture);
                        }
                        if (hasUv2Channel && SettingsMenuGUI.Instance.ModifyUV2)
                        {
                            remappedUVs2[j] = Utils.ReMapUV(remappedUVs2[j], atlasWidth, atlasHeight, texReuseMgr.GetTextureRefPosition(objectsToOptimizeSlice[i]), instance.name, generatedTexture);
                        }
                        if (hasUv3Channel && SettingsMenuGUI.Instance.ModifyUV3)
                        {
                            remappedUVs3[j] = Utils.ReMapUV(remappedUVs3[j], atlasWidth, atlasHeight, texReuseMgr.GetTextureRefPosition(objectsToOptimizeSlice[i]), instance.name, generatedTexture);
                        }
                        if (hasUv4Channel && SettingsMenuGUI.Instance.ModifyUV4)
                        {
                            remappedUVs4[j] = Utils.ReMapUV(remappedUVs4[j], atlasWidth, atlasHeight, texReuseMgr.GetTextureRefPosition(objectsToOptimizeSlice[i]), instance.name, generatedTexture);
                        }
                    }
                    else
                    {
                        if (SettingsMenuGUI.Instance.ModifyMainUV)
                        {
                            remappedUVs[j] = Utils.ReMapUV(remappedUVs[j], atlasWidth, atlasHeight, texturePos[i], instance.name, generatedTexture);
                        }
                        if (hasUv2Channel && SettingsMenuGUI.Instance.ModifyUV2)
                        {
                            remappedUVs2[j] = Utils.ReMapUV(remappedUVs2[j], atlasWidth, atlasHeight, texturePos[i], instance.name, generatedTexture);
                        }
                        if (hasUv3Channel && SettingsMenuGUI.Instance.ModifyUV3)
                        {
                            remappedUVs3[j] = Utils.ReMapUV(remappedUVs3[j], atlasWidth, atlasHeight, texturePos[i], instance.name, generatedTexture);
                        }
                        if (hasUv4Channel && SettingsMenuGUI.Instance.ModifyUV4)
                        {
                            remappedUVs4[j] = Utils.ReMapUV(remappedUVs4[j], atlasWidth, atlasHeight, texturePos[i], instance.name, generatedTexture);
                        }
                    }
                }
                remappedMesh.uv = remappedUVs;
                if (hasUv2Channel)
                {
                    remappedMesh.uv2 = remappedUVs2;
                }
                if (hasUv3Channel)
                {
                    remappedMesh.uv3 = remappedUVs3;
                }
                if (hasUv4Channel)
                {
                    remappedMesh.uv4 = remappedUVs4;
                }

                if (objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer)
                {
                    instance.GetComponent <SkinnedMeshRenderer>().sharedMesh = remappedMesh;
                    Undo.RecordObject(objectsToOptimizeSlice[i].GameObj.GetComponent <SkinnedMeshRenderer>(), "Active Obj");
                }
                else
                {
                    instance.GetComponent <MeshFilter>().sharedMesh = remappedMesh;
                    Undo.RecordObject(objectsToOptimizeSlice[i].GameObj.GetComponent <MeshRenderer>(), "Active Obj");
                }

                //if the gameObject has multiple materials, search for the original one (the uncombined) in order to deactivate it
                if (objectsToOptimizeSlice[i].ObjWasCombined)
                {
                    if (objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer)
                    {
                        objectsToOptimizeSlice[i].UncombinedObject.GetComponent <SkinnedMeshRenderer>().enabled = false;
                    }
                    else
                    {
                        objectsToOptimizeSlice[i].UncombinedObject.GetComponent <MeshRenderer>().enabled = false;
                    }
                }
                else
                {
                    if (objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer)
                    {
                        objectsToOptimizeSlice[i].GameObj.GetComponent <SkinnedMeshRenderer>().enabled = false;
                    }
                    else
                    {
                        objectsToOptimizeSlice[i].GameObj.GetComponent <MeshRenderer>().enabled = false;
                    }
                }

                if (generatePrefabsForObjects && !combineMeshesFlags[i])//lets not generate a prefab for an object that is marked for combine as later on will be combined and made a prefab
                {
                    string prefabName = Utils.GetValiName(instance.name) + " " + instance.GetInstanceID();
                    string assetPath  = folderToSavePrefabs + Path.DirectorySeparatorChar + prefabName;
                    Utils.GeneratePrefab(instance, assetPath, objectsToOptimizeSlice[i].UsesSkinnedMeshRenderer);
                }
                //useful only when building hierarchies
                //instanceID of the transform as we are comparing against parent transforms when building hierachies
                int originalOptimizedObjectInstanceID = objectsToOptimizeSlice[i].ObjWasCombined ? objectsToOptimizeSlice[i].UncombinedObject.transform.GetInstanceID() : objectsToOptimizeSlice[i].GameObj.transform.GetInstanceID();
                optimizedObjects.Add(new Tuple <GameObject, int>(instance, originalOptimizedObjectInstanceID));
            }
            GameObject.DestroyImmediate(trash);
        }