public bool VerifyNumOfVertices(BaseMaterialsAgainstDependencies BaseMat, MeshFilter meshFilterToAdd) // Checks if the subMesh will have too many Vertices.
    {
        float currentNumOfVertices = 0;

        foreach (MeshFilter localFilter in BaseMat.MeshFiltersThatRequireBaseMaterial)
        {
            currentNumOfVertices += localFilter.sharedMesh.vertexCount;
        }

        int numOfVerticesToAdd = meshFilterToAdd.sharedMesh.vertexCount;

        // Ensures that there are not too many vertices.
        // If there are too many Split it
        if (currentNumOfVertices + numOfVerticesToAdd > maxNumberOfVerticesForSubMeshes)
        {
            return(false);
        }

        return(true);
    }
    public void MyOwnAdvancedMeshCombinder()
    {
        BaseMaterialsRequired.Clear();

        List <GameObject> objectsToMerge = new List <GameObject>();

        Debug.Log("Number of objects wanted to Merge: " + GameObjectsToMerge.Count);

        // Iterate through every object that should be merged.
        // Getting a reference to all their mesh filters.  ( unless they are supposed to be ignored )
        foreach (Transform ObjToMerge in GameObjectsToMerge)
        {
            foreach (MeshFilter filter in ObjToMerge.GetComponentsInChildren <MeshFilter>(false)) // Loops through every MeshFilter that is active on its children.
            {
                // Ensures any objects that have the ignore merge tag or this object from being merged.
                if (filter.transform.tag != "IgnoreFromMeshMerge" && filter.transform != transform)
                {
                    objectsToMerge.Add(filter.gameObject);
                }
            }
        }


        // Now that we know what to merge.

        if (isDebugging)
        {
            Debug.Log("Number of objects ready to merge: " + objectsToMerge.Count);
        }

        // Now split the objects mesh filters into lists based on their Material.
        int localMatSubIndex = 0;

        foreach (GameObject obj in objectsToMerge)
        {
            // Get all the materials on this object.
            Material[] localMaterials = obj.GetComponent <Renderer>().sharedMaterials; // Usually only one material.

            localMatSubIndex = 0;

            // Loop through all the local materials, to check if you need to add another material.
            foreach (Material localMat in localMaterials)
            {
                bool isTheMaterialAlreadySetUP = false;

                // If the locally required material is already defined. Then don't worry about it. Otherwise add it.
                foreach (BaseMaterialsAgainstDependencies baseMat in BaseMaterialsRequired)
                {
                    //Debug.Log("baseMat " + localMat);

                    if (baseMat.BaseMaterial == localMat)
                    {
                        // This material already has a dependency set up, soo add its mesh filter.
                        // But first check their wont be too many vertices.
                        MeshFilter localMaterialsFilter = obj.GetComponent <MeshFilter>();

                        if (VerifyNumOfVertices(baseMat, localMaterialsFilter)) // If there is enough vertices spare to add the mesh.   // If it is not verified then The materialAlreadySetUp will stay false.
                        {                                                       // Causing another sub mesh to be generated.
                            baseMat.MeshFiltersThatRequireBaseMaterial.Add(localMaterialsFilter);
                            baseMat.MeshFilterSubIndex.Add(localMatSubIndex);
                            isTheMaterialAlreadySetUP = true;
                            break;
                        }
                    }
                }


                if (!isTheMaterialAlreadySetUP) // The material has not been set up as a dependancy
                {
                    // Create a new BaseMaterial
                    // Set its base material
                    BaseMaterialsAgainstDependencies newBaseMat = new BaseMaterialsAgainstDependencies();
                    newBaseMat.BaseMaterial = localMat;

                    // Add the material that relies on it's mesh filter.
                    MeshFilter localMaterialsFilter = obj.GetComponent <MeshFilter>();
                    newBaseMat.MeshFiltersThatRequireBaseMaterial.Add(localMaterialsFilter);
                    newBaseMat.MeshFilterSubIndex.Add(localMatSubIndex);

                    // Finally add it as a new base material.
                    BaseMaterialsRequired.Add(newBaseMat);
                }

                localMatSubIndex++;
            }
        }

        // Now that we have a 2d array of the Mesh filters against their required Material. We should Squish them down into a submesh per Material.
        int index;

        foreach (BaseMaterialsAgainstDependencies baseMat in BaseMaterialsRequired)
        {
            if (isDebugging)
            {
                Debug.Log("Material " + baseMat.BaseMaterial + " Has " + baseMat.MeshFiltersThatRequireBaseMaterial.Count + "Dependencies.");
            }

            // Create a list of CombineInstances to store all of the info we need for each filter within this current material to combine into one.

            List <CombineInstance> combinersForEachFilterPerMaterial = new List <CombineInstance>();

            index = 0;

            foreach (MeshFilter filter in baseMat.MeshFiltersThatRequireBaseMaterial)
            {
                CombineInstance Ci = new CombineInstance();

                if (!filter.sharedMesh.isReadable)
                {
                    Debug.Log(filter.transform.parent.transform.name + " - Is not readable!!!");
                }

                Ci.mesh         = filter.sharedMesh;
                Ci.subMeshIndex = baseMat.MeshFilterSubIndex[index];
                Ci.transform    = filter.transform.localToWorldMatrix;

                combinersForEachFilterPerMaterial.Add(Ci);

                index++;
            }

            // Creates a new mesh that is a combination of all the meshes that require this material.

            Mesh newMesh = new Mesh();
            newMesh.CombineMeshes(combinersForEachFilterPerMaterial.ToArray(), true);
            baseMat.SubMesh = newMesh;

            if (isDebugging)
            {
                Debug.Log("This Submesh has: " + baseMat.SubMesh.vertexCount + " Vertices");
            }
        }

        // Finally combine all the meshes.

        List <CombineInstance> finalCombiners           = new List <CombineInstance>();
        List <Material>        currentMaterialsRequired = new List <Material>();
        int currentVertices = 0;

        for (int baseMaterialIndex = 0; baseMaterialIndex < BaseMaterialsRequired.Count; baseMaterialIndex++)
        {
            CombineInstance ci = new CombineInstance();
            BaseMaterialsAgainstDependencies baseMat = BaseMaterialsRequired[baseMaterialIndex];

            ci.mesh         = baseMat.SubMesh;
            ci.transform    = transform.worldToLocalMatrix;
            ci.subMeshIndex = 0;

            if (isDebugging)
            {
                Debug.Log("Adding " + baseMat.BaseMaterial + " with " + ci.mesh.vertexCount);
            }

            int verticesInMesh = ci.mesh.vertexCount;

            if (currentVertices + verticesInMesh > maxNumberOfVerticesForMeshes) // Need to create a new mesh, Over the Mesh Vertex limit.
            {
                // Create Mesh for last.
                CreateNewMesh(finalCombiners.ToArray(), currentMaterialsRequired.ToArray());

                // Clear everything.
                currentMaterialsRequired.Clear();
                currentVertices = 0;
                finalCombiners.Clear();

                // Set up for next mesh.
                finalCombiners.Add(ci);
                currentMaterialsRequired.Add(baseMat.BaseMaterial);
                currentVertices += verticesInMesh;

                // On the odd Chance that this is also the last run.
                if (baseMaterialIndex == BaseMaterialsRequired.Count - 1)
                {
                    // Create new mesh.
                    CreateNewMesh(finalCombiners.ToArray(), currentMaterialsRequired.ToArray());

                    // Clear for next use.
                    currentMaterialsRequired.Clear();
                    currentVertices = 0;
                    finalCombiners.Clear();

                    if (isDebugging)
                    {
                        Debug.Log("Mesh - Fnished Generating Mesh");
                    }

                    /// Do whatever after gen is finished \\\
                }
            }

            else if (baseMaterialIndex == BaseMaterialsRequired.Count - 1) // This is the final run. So finish up and create the new mesh.
            {
                // Make up for final run
                finalCombiners.Add(ci);
                currentMaterialsRequired.Add(baseMat.BaseMaterial);

                // Create new mesh.
                CreateNewMesh(finalCombiners.ToArray(), currentMaterialsRequired.ToArray());

                // Clear for next use.
                currentMaterialsRequired.Clear();
                currentVertices = 0;
                finalCombiners.Clear();

                if (isDebugging)
                {
                    Debug.Log("Mesh - Fnished Generating Mesh");
                }
            }

            else // Keep Looping.
            {
                currentVertices += verticesInMesh;
                finalCombiners.Add(ci);
                currentMaterialsRequired.Add(baseMat.BaseMaterial);
            }
        }

        // Hide the original meshes.
        foreach (Transform objToMerge in GameObjectsToMerge)
        {
            SetActiveAllChildren(objToMerge, false);
        }
    }