How to deal with the slow MeshCollider.SharedMesh?

Hello

I must recalculate often a MeshCollider.sharedMesh but unfortunately it is really slow. It seems really not well optimised. I can generate a procedural mesh with all the triangles, normals and uv in ~0.12 sec but the sharedMesh will take around 1.2 sec!!!

I tried to use a coroutine to -at least- put the calculation in background but it doesn’t seem to work: the application still stalls during the calculation.

  • Is my code wrong?

  • Or am I right in supposing that the recalculation of the shared mesh cannot be put in background?

  • As I don’t need a collider 100% precise can calculation be speed up by generating a “simplified” collider?

  • Any ideas how I could speed up this?

  • Alternatively -if we can’t speed up the collider update- is there a non-collider based raycast that can detect the triangles in a mesh?

C#

	{
	...
	StartCoroutine(UpdateColliderMesh(mf.mesh));
	...
	}

	IEnumerator UpdateColliderMesh(Mesh mesh) {
		MeshCollider mc = (MeshCollider)
		   test.GetComponent(typeof(MeshCollider));
		yield return mc.sharedMesh = mesh;
	}

Coroutines aren’t separate threads. You can use real threads with System.Threading, but only .net classes, nothing Unity-specific, because Unity functions are not thread-safe and will crash randomly. (Which is too bad, because recalculating a mesh collider in a separate thread works very nicely, except for the times when it crashes…)

Yes, that’s a good idea.

–Eric

To bad :frowning:
I would be great if Unity added hooks that permit us to update the sharedmesh safely.

Euh… I meant is there a unity parameter that permits to generate simplified collider from a mesh?
Or do we need to ask for a new feature?

No, but you can make a simplified mesh in a 3D app and use that for the collider.

–Eric

No. As I said in the first post I must update the collider each time the mesh is modified. Btw it is not a game application.

So if I can’t generate a simplified collider it seems I can’t use the collider approach.

  • Is there a non-collider based raycast that can detect the triangles in a mesh?

Not sure what either of those have to do with what I said. See attached pic…when the high-res mesh (blue) is deformed at runtime, the low-res mesh (green, the actual collider) has the same code applied to it. Both were modeled in a 3D app.

No.

–Eric

Oh… you are modifying simultaneously both meshes?
You are setting the meshCollider.sharedMesh.vertices and .triangles ?

I will try that.

Yes, but just .vertices, because the triangles don’t change. Also I’m not using .sharedMesh, just .mesh, because I don’t want to modify everything that uses that mesh, just that particular instance.

–Eric

Wow… it works

I am a total lose to understand the time difference between:

1.3 sec

mc.sharedMesh = cmesh.mesh;

0.1 sec

//mc.sharedMesh.Clear(); 
mc.sharedMesh.vertices = cmesh.vertices;
mc.sharedMesh.uv = cmesh.uv;
mc.sharedMesh.triangles = cmesh.triangles;
mc.sharedMesh.normals = cmesh.normals;
mc.sharedMesh.RecalculateBounds();

Is there something else important going on?

Anyway I can continue with my app
Thanks Eric5h5

Ah no… The collider mesh doesn’t seem to update.

Doing something wrong, what?

MeshColliders have to do a great deal of processing before they can be used for physics calculations. When you directly set mc.sharedMesh = mesh, Unity will detect a change, and will re-generate some behind-the-scenes data. If you just set the vertices however, this will not be the case. That’s why when you individually set mesh.vertices = vertices, etc. It runs slower, and doesn’t effect the collision volume.

I’ve been messing with mesh deformation for a school project of mine, and I ran into the same issue. Hope this answers the question for anyone who’s curious in the future!