CombineMesh not working as expected

Hi there, I’m trying to combine meshes for grass in my game and I’ve been following the documentation but it doesn’t seem to be working for me and I’m not sure what’s wrong.

I’m following the code in the example on this page: Unity - Scripting API: Mesh.CombineMeshes

My code is identical to that page except I added a few Debug.Logs to see what’s happening.

All my grass uses the same material and I have that same material on the parent object’s MeshRenderer as well (the object that holds the MeshCombine script).

So the script is running, and it is deactivating all my grass objects as well as adding them to the meshFilters array.

Problem is, even though the parent object is active, and I can see that it has created a new mesh in its mesh filter, I can’t see anything. All the grass is just gone.

Any idea what’s going on? I’m guessing I’m missing some setting or something.

For some period of time there was broken CombineMesh code circulating. Perhaps you got some of that?

Whatever the problems were (I forget but there were two or three issues that people kept seeing), I have a fully-operational mesh combination example in my MakeGeo project. Just search for “combine”

MakeGeo is presently hosted at these locations:

https://bitbucket.org/kurtdekker/makegeo

https://github.com/kurtdekker/makegeo

@Kurt-Dekker

Thanks for the reply. So I found the ExampleCombinerImproved script which I’m fairly sure is the one in question. It’s working well for standard meshes, but not for my grass. Here is a gif of what’s going on when I hit play:

7707514--965872--Mesh Combine 01.gif

So the cube is the parent with the script, the spheres and the grass are children with mesh filters. The spheres use a standard material, and the grass uses a material with my grass sprite sheet and a custom shader. I tried this on a new project as well, without my custom shader, but the same grass mesh I’m using, and it does this where it sort of merges with the spheres.

Not sure why this would be happening to the grass mesh. Any ideas?

Well what’s moving the grass vertices? It seems like maybe that logic is grabbing the source vertex positions off the brown orbs, animating it and applying it to the grass verts!

The custom shader is moving the vertices, but when I tried it with a regular material on the same grass mesh, I had the same result (except it wasn’t moving) but it ended up inside one of the spheres.

Certainly smells like the combine has a bug. No idea why it only manifests on the grass but perhaps it is related to submesh number or who knows. Did you try it with the combiner in MakeGeo? I bet it will work… don’t know about the shader displacement stuff though.

EDIT: I see you did try it with the script, never mind.

EDIT2: why does the cube AND the nearest brown ball go away. That seems also suspect. Are you sure you are ONLY running the code from MakeGeo?

So Here is the result in a brand new project:

7707712--965902--Mesh Combine 02.gif

Same deal as before, cube is parent, grass mesh is the green mesh, and the other 6 are Unity 3D objects (spheres, cylinder, and quad). Both materials used are standard and use the standard shading, one is transparent, the other opaque. No custom shaders at all.

The grass mesh seems to be putting it’s material on one of the other meshes and disappearing, or maybe taking the shape and position of the other mesh? Not sure.

Here is the code, it’s just copy paste from the linked project unless I messed something up but I think it’s all the same.

public class MeshCombiner : MonoBehaviour
{
    private void Start()
    {
        MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
        List<CombineInstance> combines = new List<CombineInstance>();

        // KurtFixed: handle materials... I mean, they're kind of important!
        List<Material> materials = new List<Material>();

        for (int i = 0; i < meshFilters.Length; i++)
        {
            // KurtFixed: we gotta ignore ourselves or our count would be off!
            if (meshFilters[i] == GetComponent<MeshFilter>())
            {
                continue;
            }

            // KurtFixed: tally up the materials, since each mesh could have multiple
            var mr = meshFilters[i].GetComponent<MeshRenderer>();
            for (int j = 0; j < mr.materials.Length; j++)
            {
                var combine = new CombineInstance();

                combine.mesh = meshFilters[i].sharedMesh;
                combine.subMeshIndex = j;

                combine.transform = meshFilters[i].transform.localToWorldMatrix;
                meshFilters[i].gameObject.SetActive(false);

                combines.Add(combine);

                materials.Add(mr.materials[j]);
            }
        }
        transform.GetComponent<MeshFilter>().mesh = new Mesh();
        transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combines.ToArray(), false);
        transform.gameObject.SetActive(true);

        // KurtFixed: inject the original materials
        gameObject.GetComponent<MeshRenderer>().materials = materials.ToArray();
    }
}

Finally, here is the cube parent’s inspector, pretty sure it’s all good here too

7707712--965908--upload_2021-12-3_14-57-22.png

Not sure what’s going on, an issue with my grass mesh maybe, but I can’t imagine why.

Ok so I think I fixed it. Turns out it had nothing to do with my shader and it was a really easy fix.

The grass mesh I was using to test this and that I was trying to combine was an imported mesh and I needed to have “Read/Write Enabled” turned on in the mesh settings.

After turning that on it’s working exactly as expected :slight_smile:

2 Likes

AHA! That’s awesome! Thanks for the followup… was it printing a warning / error in the console?

Nope, nothing. Just that weird behavior shown in the gif. I only figured it out after finding this post:

https://answers.unity.com/questions/1679964/combining-meshes-from-imported-models.html

So the key was that I was using an imported mesh and I hadn’t thought to search for that specifically until today.

Man you are a genius!! This saved my day!
Thank you ma man!

1 Like

Unity now throws a warning when trying to combine meshes without read/write on.