question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

boxcastBroadphase giving erroneous minimumTranslationVectors on slopes

See original GitHub issue

I 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:closed
  • Created 7 years ago
  • Comments:20 (20 by maintainers)

github_iconTop GitHub Comments

1reaction
prime31commented, Jul 16, 2016

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.

0reactions
prime31commented, Jul 16, 2016

So, it looks like you have some Polygons here that arent centered. Their origin is a few miles away from their verts like so:

screen shot 2016-07-16 at 2 26 35 pm

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:

            foreach( var obj in tiledMap.getObjectGroup( "Collisions" ).objects )
            {
                var center = Polygon.findPolygonCenter( obj.polyPoints );
                var entity = createEntity( "poly-col" );
                entity.transform.setPosition( center );

                for( var i = 0; i < obj.polyPoints.Length; i++ )
                    obj.polyPoints[i] -= center;

                entity.addCollider( new PolygonCollider( obj.polyPoints ) );
            }

On a side note, I made a couple minor mods to the BoxController2D script. You can see the diff here.

Read more comments on GitHub >

github_iconTop Results From Across the Web

We need a way to detect and resolve collision hits manually
Manually resolve collisions using the computed penetration information of step 2; Use penetration information of step 2 to also determine things ...
Read more >
Changelog | Unity Physics | 1.0.11
The data protocol for static rigid bodies has changed so that at least one of Translation , Rotation , or LocalToWorld is required....
Read more >
Change Log | Unity Physics | 0.6.0-preview.3
Fixed the issue where ExportPhysicsWorld system would not get run if there wasn't at least one entity that has PhysicsCollider component. Fixed ...
Read more >
UnityEngine.PhysicsModule.xml
Single&)"> <summary> <para>Compute the minimal translation required to separate the given colliders apart at specified poses.
Read more >
UnityEngine.PhysicsModule.xml
slopeLimit"> <summary> <para>The character controllers slope limit in degrees. ... joint giving you complete control over rotation and linear motion.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found