(Edit: I’d made a mistake in my original repro project. Having checked again, I’m only seeing the problem with convex MeshCollider/TerrainCollider interactions, which matches what I was seeing in my game - I’ve edited the title and the stuff below to match, the replies in the thread are still relevant. It’s like the contactOffset is being ignored only in the case of MeshCollider/Terrain interactions).
This feels like a bug to me, I’m running the same code on BoxCollider (fine) and “identical” box-shaped convex MeshCollider (jitter). Wondering if anyone has seen this or has advice (a workaround would be great!) before I just submit it as a bug (assuming the bug is not me, somehow:).
I’ve attached a 42k minimum repro project.
What we’re actually trying to achieve is, we’re using Trax so that normally our vehicle looks like it’s sunk ~20cm into the sand, but actually the visual sand that we plough through is higher than the collider. So with contact modification we can sink further, but not too far or it falls through; so if we modify the separation in the other direction, we can make the vehicle sit on the actual visual surface of the sand, and only sink when we want it to.
Description:
1kg cubes with Rigidbody or Articulationbody on a default plane, or default terrain can be made to sink into the terrain or hover above it by setting ModifiableContactPair.SetSeparation; however, setting a negative value with MeshCollider cubes (over terrain only) causes significant jitter; BoxCollider cubes behave as expected. MeshCollider cubes above a Plane (MeshCollider) also behave as expected.
Repro:
(SetSeparation sets the separation to -restOffset, so the +/- sense is flipped compared to the slider value)
Open Scenes\SetSeparationBug
Play the repro project, select the ScriptHolder in the Hierarchy.
Slowly move the restOffset slider to -0.2. All cubes sink into the ground as expected.
Now slowly move the slider to +0.2: green BoxCollider cubes hover above the ground as expected, but red Convex MeshCollider cubes over the terrain jump around (red cubes over the plane work fine). I’d expect all cubes to behave the same way, regardless of the collider type.
Tested & reproduced in:
Unity 2021.3.33f1 LTS (using for our game);
Unity 2021.3.45f1 LTS (latest 2021 LTS, so probably a safe upgrade path for us)
Unity 2022.3.57f1 LTS (what I thought was latest LTS; a bit worried about switching to a new major version);
Unity 6000.0.36f1 LTS (latest LTS? But it’s recent & at .0, not .3? Even more worried:) SetSeparationBug.zip (42.1 KB)
Check the actual collision mesh. Those will be different.
Generally speaking, MeshColliders are problematic every way you look at them and IMO only exist as a quickshot solution to have anything (approximately) collide with things without putting any effort in.
The most important bit about MeshCollider not working as expected is the IsConvex checkbox. You must only check this if the collision mesh is truly convex. Even if it’s just 1 mm off at some vertex you can start to have issues.
Here I would expect that the code paths are wholly different. The box collider can perform a simple Rect intersects test (or equivalent in 3d space) whereas the MeshCollider has to perform a collision geometry test for each individual triangle, and since they are likely two per each flat cube surface, the behaviour is prone to be more or less different. But I’m just making an educated guess, didn’t check your project.
That, and because MeshColliders are awful performance hogs, is why most devs would avoid them and rather construct complex collision geometry out of individual primitive colliders. There are assets in the store that help with the creation and editing of such combined primitive colliders.
Well, I only put cubes and stuff in my repro project to make it easy to see what’s going on.
In our actual game, I’m not sure it’s feasible to switch out our current procedural wheel mesh colliders for compound primitives. Like, maybe (I mean, I’ve considered using sphere colliders and using maths and contact modification to approximate bevelled cylinders, but, it feels fraught:), but if this is a bug, it’s better to fix it?
Like, surely this (green BoxCollider, red MeshCollider that Unity gives me when I click “Convex” on the cube mesh) isn’t right (Edit:only the red cubes above the terrain jump around now, originally I wasn’t applying the contactOffset to the red cubes at all, sorry)
I didn’t fully understand the part about “sinking” into the floor respectively hovering above it. Could it have anything to do with that?
It looks like the red boxes would like to fall down due to gravity but at the same time get pushed back up which is why they start to dance around. At least that’s what it looks like.
After all, if I understand the concept correctly, the colliders aren’t actually colliding if you hover them upwards. Right?
Are you scaling the colliders in any way? Because that would also cause physics to muck up.
You could also try playing with the Phyics settings. Like collision distance threshold and number of iterations and the “stability” setting to see if this affects the behaviour.
I’m using Unity’s contact modification API to alter the separation reported to the physics simulation. It’s giving the same effect as physX’s restOffset, which I don’t think Unity exposes.
I’ve modfied the contactOffset so that the colliders will generate collisions “early”, and then I can decide what to do with them in code.
I’m not using scaling; but even if I was, I’d expect all of the boxes to behave the same. The only difference between the red and green boxes is the type of collider.
My game project uses different fixedTime and solver iterations, it doesn’t seem to make a difference; but again, I’d expect at least similar behaviour.
This has the same vibe to me as this problem I reported and was fixed a while ago, which I was able at the time to patch around by modifying the normals in the contact mod API before they got as far as the physics simulation:
Hopefully someone at Unity is looking at this and will be all “oh no, I know exactly what that is, please let me fix it rn~”