MeshCollider is not getting updated when adding vertex to mesh

I have created a simple piece of code for adding vertices to a mesh by clicking on it. The vertex is added to the point of the mesh which is clicked. This works very well the first time. But the second time it fails to get the correct triangle from RaycastHit.triangleIndex. Here is the code, including a hack which actually makes it work. (The fact that the hack works also eliminates the possibility of this being a corrupted mesh.)

public void AddVertexScreenPos(Vector2 screenPos)
{
RaycastHit hit;
if (HitScreenPos(Input.mousePosition, out hit))
{
if (hit.collider.GetType() == typeof(MeshCollider))
{
MeshCollider meshCollider = (MeshCollider)hit.collider;
Mesh mesh = meshCollider.GetComponent().mesh;
List vertices = new List(mesh.vertices);
List triangles = new List(mesh.triangles);

vertices.Add(meshCollider.transform.InverseTransformPoint(hit.point));

int[ ] triangleHit = GetTriangleIndices(ref hit);

triangles.Clear();

triangles.AddRange(RemoveTriangle(hit.triangleIndex, mesh.triangles));

for (int i = 0; i < triangleHit.Length; i++)
{
triangles.Add(triangleHit[i % triangleHit.Length]);
triangles.Add(triangleHit[(i + 1) % triangleHit.Length]);
triangles.Add(vertices.Count - 1);

}

mesh.vertices = vertices.ToArray();
mesh.triangles = triangles.ToArray();
mesh.RecalculateNormals();
mesh.RecalculateBounds();

//The following line should update the meshCollider, but it fails.
//meshCollider.sharedMesh = mesh;

//Hack. This fixes the problem
GameObject go = hit.transform.gameObject;
GameObject.DestroyImmediate(meshCollider);

go.AddComponent();
//Hack end.

}
}

}

Any suggestions?

Very slow… but you can do this…

Destroy(meshCollider);
meshCollider = mesh.gameObject.AddComponent();

A component won’t work and would be slow anyway. mesh.gameObject

Thx for the replies. But this is the exact thing that I’m trying to avoid. I actually think this might be a bug?

Ok, the only way around this is to create seperate gameobjects that store the new vertices and then add the mesh collider as normal. That way it wont recreate the meshcollider for the entire mesh.

You could probably put some smarts into it that checks to see how many vertices exist in the current model and if it’s above a certain number, create a new gameobject to avoid the performance hit.

Make sure you use the same material so that batching still works.

This is definitely a bug.

I just spent several hours with this today and did the same workaround.

I was creating new mesh parts, then mesh.CombineMeshes, then setting the mesh to the MeshCollider.

When you set the mesh to the collider the first time, it works.

When you set it a second time:
-The Inspector panel will indicate that there is a new shaped mesh assigned to the mesh collider. I renamed the meshes with a count to see this happen.
-The actual collision mesh is still the first mesh set.

If its intended that we destroy the collider component then the Inspector should not update with the new mesh name and it should throw an error, or warning.

But since the Inspector is showing the new mesh in the collider I have to assume that
mesh collider.sharedMesh= MeshFilter.mesh (or sharedMesh)
is broken and does not properly set the collider to the new mesh if it already has a mesh.

Well after some more testing today, there is another option.

I’m using CombineMeshes. In that example code there is this line.

transform.GetComponent().mesh = new Mesh();

When you make a new mesh, then assign that to a MeshCollider.sharedMesh, the new collider shape will work.

Thats the good news, the bad news is that this increases VBO total and Mem and Vram mem

If you destroy the old mesh first, then create the new, this still increases VBO total but the mem and Vram mem stay steady and only increase as expected.

I dont know if a large VBO Total is a bad thing. This is the reason I switched over to BoxColliders months ago.
For a large world BoxColliders are a problem, so I wanted to try MeshColliders again with RayCasting to figure out were a click is.

These two options work

Option A
Destroy old mesh
create new mesh
set new elements into the new mesh
assign mesh to old MeshCollider.sharedMesh
Watch VBO total rise

Option B
Destroy MeshCollider
create new MeshCollider
assign mesh to new MeshCollider.sharedMesh
VBO stays steady

I still believe MeshCollider.sharedMesh = mesh, is broken

This also works

Option C
MeshCollider.sharedMesh=null;
MeshCollider.sharedMesh=theNewMesh;