Combining Meshes through code

Hey guys, I am making a voxel type game and I’m trying to combine my meshes into one by using, Unity - Scripting API: Mesh.CombineMeshes.

That function takes a list of MeshFilters and then combines all of their meshes into one but I am trying to hack it a bit and just combine a list of Mesh objects I have already built.

        register = new List<Mesh>();
        foreach(Block b in blocks) { b.Build(register); }

        combine = new CombineInstance[register.Count];
        for(int i = 0; i < register.Count; i++) { 
            combine[i].mesh = register[i]; 
            combine[i].transform = Matrix4x4.zero; 
        }

        m = new Mesh();
        m.CombineMeshes(combine, true);
        mf.mesh = m;

And an example of the meshes I am creating through code.

        Mesh mesh = new Mesh();
        Vector3[] v1 = new Vector3[4];
        v1[0] = new Vector3(0.5f, 0f, 0.5f);
        v1[1] = new Vector3(0.5f, 0f, -0.5f);
        v1[2] = new Vector3(0.5f, 0f, -0.5f);
        v1[3] = new Vector3(-0.5f, 0f, 0.5f);
        mesh.vertices = v1;
        mesh.triangles = new int[6] { 0, 1, 2, 0, 2, 3 };
        mesh.uv = new Vector2[] { new(0,0), new(0,1), new(1,1), new(1,0) };
        Assets.mesh.Add("square", mesh);

The mesh displays fine on its own but when I try to combine using that Mesh.CombineMeshes method it doesn’t show. But I do see that it has combined the vertices and triangles in the inspector.

Are there any code gurus that can point me in the right direction? I could create a temporary list of gameobjects and fill their meshfilters, use that, and then delete it but that doesn’t feel very performant.

I took a look at the CombineInstance and CombineMeshes methods and I can’t make any sense of it. It looks like it’s just grabbing an instance ID of the component…

    //
    // Summary:
    //     Mesh to combine.
    public Mesh mesh
    {
        get
        {
            return Mesh.FromInstanceID(m_MeshInstanceID);
        }
        set
        {
            m_MeshInstanceID = ((value != null) ? value.GetInstanceID() : 0);
        }
    }

And then somehow combining them…

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetSubMesh_Injected(int index, ref SubMeshDescriptor desc, MeshUpdateFlags flags = MeshUpdateFlags.Default);

Check out the Mesh API samples! There is a very performant version there: GitHub - Unity-Technologies/MeshApiExamples: Example project for Unity 2020.1 Mesh API improvements

Know that this might also increase render load, as the whole model will be loaded. This depends on the exact setup.
Make sure to cull/remove the non visible vertices to keep everything smooth.

1 Like