Preface:
I have characters where I disable and re-enable the character controller over the course of the game. Upon re-enabling, of course, my calls to Move will depenetrate the character from any colliders it is currently overlapping. I noticed that this depenetration worked very badly in some cases, putting the character into positions I couldn’t explain. So I did some investigation.
The problem:(EDIT: minimal example in my following post)
It turns out that Physics.ComputePenetration does not always compute the “minimal translation required to separate the given colliders apart” as the documentation claims. There seems to be a problem with capsules and mesh colliders, because this only happens with my self-generated meshes.
Look at the two visualizations I attached. The extruded hexagon is the self-generated mesh with a convex mesh collider attached. I wrote a small demo script that visualizes the calculated depenetration with a magenta-colored line.
In the first image, where the capsule is near the center of the mesh and overlaps the mesh slightly through its top face, everything is fine: ComputePenetration yields a small vector pointing up.
However, when I move the capsule further to the edges of the mesh (second image - same Y coordinate), whatever ComputePenetration returns is definitely not the “minimal” depenetration (which should be the same as in the first image).
And this explains exactly why my character ends up at unexplainable places (in this case, it would end up on the other side of the object).
So I wonder: What is happening here? Am I doing something wrong badly with setting up the mesh collider (which is convex and seems to work fine apart from this)? Is this a known bug perhaps?
There are no known bugs, so I suggest you file one or dig a little deeper. I use compute pen on a daily basis with my custom capsule controller and haven’t met any issues yet. Are your normals ok?
Yes, although the mesh collider manual states that normals aren’t used by the physics system.
The mesh only has faces on the top, not the bottom, but the same problem occured when I generated bottom faces too.
First collider I’m passing is the capsule, second is the mesh. But it’s a static method, so there is no “source” is there? Anyway, the script calling the compute is on the character (ie the capsule).
Scale is 1,1,1 on both.
I’m attaching a minimal example that demonstrates this. If it’s a bug, I’d want to create one anyway.
Just hit play and switch to the scene view to see the capsule’s Gizmos. The “MeshGenerator” scripts generates the mesh, the “PenetrationTester” is the script on the capsule that calls the ComputePenetration method.
Your reply reminded me of this thread so I gave it a test. Commenting out mc.convex = true; enables everything to work as expected. It’s bizarre but it should allow you to carry on developing as you wait for resolution.
I do use it with mesh and convex colliders but I do not generate any meshes, so this does actually look like a bug.
I’ve been doing a battery of tests since your last post and discovered a situation where computePenetration actually just plain skips processing on 1 frame sometimes (capsule vs static mesh collider).
Interesting. I was beating my head around a similar issue. I was creating a solution to dynamically create colliders and my collision tests it never returned true.
Then I changed one thing before checking collisions… Physics.autoSyncTransforms = true;
Afterwards, all of my collision tests worked correctly.
This may not fix your issue, but I thought I post my solution just in case it helps.
I set Physics.autoSyncTransforms back to false once I finish generating my colliders.
edit: Opps, Guess, I should have downloaded your example first. This is a completely different problem.