- Home /
Dynamic mesh collider
I'm generating a mesh at runtime to create terrain. Generating the mesh is running fine, mapping UVs is good, and the bounding box is working properly. However, there is a slight issue with there not being any kind of collisions.
It has a mesh collider attached to it, and the generated mesh is getting passed to the collider, however it is ignoring this mesh. I have also found that if i set the collider to Convex in the unity editor then change it back the collider works as it should. I have tried changing the collider to convex in the code, but this doesn't seem to do the same thing as clicking the check box. This says to me that there is some function call that takes place when you check the box in the editor. Since I can't very well click this check box in the finished game, does anyone know about this? I've seen other people dynamically generating mesh colliders with no trouble, but none of them have mentioned this issue.
Creating a mesh of 1024 vertices takes 0,02 seconds in Unity, but making the mesh collider takes 0.3 seconds at least...
So you can only make 1/10th the colliders that you can make the mesh... mesh colliders are precalculated to be objects with mass that can bounce many ways and have many materials, unlike the terrain.
i would recommend to make a custom collider code that bounces things if they go underneath, i am about to post a question about custom physics as i cant find the answer.
Answer by Kos-Dvornik · Jun 23, 2012 at 06:47 PM
You should apply sharedMesh in MeshCollider AFTER any operation with Object mesh gonna be DONE. So simply put assign code at the BOTTOM. For example:
WRONG:
Mesh m = (gs[i].GetComponent(typeof(MeshFilter)) as MeshFilter).mesh;
MeshCollider theMeshCollider = gs[i].GetComponent(typeof(MeshCollider)) as MeshCollider;
theMeshCollider.sharedMesh = m;
m.triangles = someTriangles;
CORRECT:
Mesh m = (gs[i].GetComponent(typeof(MeshFilter)) as MeshFilter).mesh;
m.triangles = someTriangles;
MeshCollider theMeshCollider = gs[i].GetComponent(typeof(MeshCollider)) as MeshCollider;
theMeshCollider.sharedMesh = m;
Answer by Ming · Nov 04, 2011 at 02:57 PM
Ah, I figured out the answer.
When looking into this, I noticed that the bounds on my new meshCollider was zero area. I tried to set the bounds on the meshCollider, but it didn't work. I investigated further.
So, it seems that if you have this:
MeshCollider myMC = GetComponent<MeshCollider>();
myMC.sharedMesh = new Mesh();
myMC.sharedMesh.vertices = newverts;
myMC.sharedMesh.triangles = newtris;
myMC.sharedMesh.RecalculateBounds();
Then RecalculateBounds won't actually do anything. Setting the bounds directly also won't change the bounds on myMC even if it changes it on myMC.sharedMesh.
To set the bounds on myMC properly, you must assign myMC.sharedMesh after the mesh has been created an populated with vertices.
So the new code looks like:
MeshCollider myMC = GetComponent<MeshCollider>();
Mesh newMesh = new Mesh();
newMesh = new Mesh();
newMesh.vertices = newverts;
newMesh.triangles = newtris;
newMesh.RecalculateBounds();
myMC.sharedMesh = newMesh;
$$anonymous$$esh my$$anonymous$$esh = GetComponent< $$anonymous$$esh >();
.......
my$$anonymous$$esh.RecalculateBounds();
$$anonymous$$eshCollider my$$anonymous$$C = GetComponent< $$anonymous$$eshCollider >();
my$$anonymous$$C.shared$$anonymous$$esh = null;
my$$anonymous$$C.shared$$anonymous$$esh = my$$anonymous$$esh;
This should make sure the $$anonymous$$eshCollider updates to match the $$anonymous$$esh Bounds
Answer by Ming · Nov 04, 2011 at 02:20 PM
I have the same issue.
I used sharedMesh to create the new mesh, so that's not an issue.
I noticed that clicking any of the following on and then off enables the new mesh collision to work (IsTrigger, Smooth Sphere Collisions, Convex). Apparently, there is some sort of initialization done by the Editor with this clicks that allows it to work.
Hi, I know your answer was a long time ago, anyway, I still encounter this problem and your solution is the same thing that happened to me, any other way to solve it? cause I can't use the editor during game time...
Answer by cupsster · Nov 03, 2011 at 07:17 PM
// Assigns an arbitrary mesh collider to the current transform
var meshToCollide : Mesh;
if(!meshToCollide) {
Debug.LogError("Assign a mesh in the inspector");
return;
}
transform.gameObject.AddComponent(MeshCollider);
transform.GetComponent(MeshCollider).sharedMesh = meshToCollide;
I think you must access shared mesh instead.