boxcastBroadphase giving erroneous minimumTranslationVectors on slopes
See original GitHub issueI have a basic character controller set up, and I’m importing some non-rectangular collision polygons from a tiled map.
When the player character moves, I have a boxcast set up to correct any intersections (like in the platformer example in Nez.Samples).
Here’s a sample of the code I’m working with -
......
entity.colliders.unregisterAllCollidersWithPhysicsSystem();
....
foreach (var neighbor in neighbors)
{
if (neighbor.isTrigger)
continue;
if (collider.collidesWith(neighbor, velocity, out collisionResult))
{
velocity -= collisionResult.minimumTranslationVector;
}
Debug.log($"translationvector: {collisionResult.minimumTranslationVector.X}, {collisionResult.minimumTranslationVector.Y}");
}
}
...
On certain areas, this works correctly. On flat ground, I might get a log
output of 0, -0.4
, which makes sense as the player’s gravity is pushing down at 0.4
.
However, on slopes, I’m getting some erratic readings - the character jumps all around and I get output such as
Log: translationvector: 0, -31.58746
Log: translationvector: 0, 0.4125366
Log: translationvector: 0, -32.00002
Log: translationvector: 0, 32.4158
Log: translationvector: 0, -31.58228
Log: translationvector: 0, 0.4177246
Log: translationvector: 0, 32.41754
It’s worth noting that my player character has a size of 32px, so there may be a relation between the jumps in Y
being ~32
I’ve stripped everything off of my character besides the boxcast to make sure it was the issue, and it still remains unfortunately.
Issue Analytics
- State:
- Created 7 years ago
- Comments:20 (20 by maintainers)
That is indeed the intended effect. When in a slope tile the center of the collider is used for collisions. Any non-slope collisions use the entire edge in the direction of movement.
If that isn’t the desired effect you can modify the code to use the front-most point as the perpendicular frontier and you’ll then get no penetration at all if that is what you want.
So, it looks like you have some Polygons here that arent centered. Their origin is a few miles away from their verts like so:
That causes the normals to be calculated incorrectly for any collisions on the left/top due to the algorithm expecting the origin to be the center of the polygon. I can probably add some defensive code to work around this particular scenario but it would be adding extra calculations to a performance critical section of code so it probably wont happen.
A much better and more performant option is to just pre-calculate the verts centered around the polygon center. I added a helper method for this (
Polygon.findPolygonCenter
) and you can see below how it can be used to wrangle those verts so that they are hovering around the polygon origin instead of a few miles east of the origin:On a side note, I made a couple minor mods to the BoxController2D script. You can see the diff here.