Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KinematicBody2D doesn't collide with one way platforms on corners in certain cases #42916

Open
Tracked by #45334
Rhathe opened this issue Oct 19, 2020 · 10 comments
Open
Tracked by #45334

Comments

@Rhathe
Copy link
Contributor

Rhathe commented Oct 19, 2020

Godot version:

3.2.3

OS/device including version:

Windows 10

Issue description:

At certain angles, KinematicBody2D objects don't collide with one way platform corners even though they should collide when the platform has one way collision turned off.

one_way

The top left object doesn't collide although the bottom left object does collide. The two right objects have their bottom edges enter underneath the top edge of each one way platform. However, the one way platforms have large collision margins, so they should both register a collision, but only the bottom right object collides with its platform.

It's expected that all 4 objects should collide with the corners, as shown when one way collision is turned off for both platforms.

non_one_way

Steps to reproduce:
Run the test project.

Minimal reproduction project:

test_move_one_way_corners.zip

@Rhathe
Copy link
Contributor Author

Rhathe commented Oct 19, 2020

This should be fixed by #38471

@madmiraal
Copy link
Contributor

madmiraal commented Oct 20, 2020

Similar to #25967, but presents more corner cases.

First, to be clear, when moving down and hitting the corner of a one-way platform, the expectation is that it either hits the top surface or it doesn't. As discussed in #42574, and beautifully illustrated by @bemyak here, the corner condition should not be treated as hitting the side of the one-way platform.

That been said, in all the examples the expectation is: If it is hitting the platform, it should collide and move to the left as suggested. If not, it should continue its trajectory. Taking each of the collisions presented in the MRP:

  1. Top left (One): At the corner, a collision is reported, so it should slide to the left as suggested. This is also fixed in Fix multiple issues with one-way collisions #42574.
  2. Top right (Two): At the corner, a collision is not reported, so it should continue its trajectory as it currently, correctly does in 3.2.3, and not, as suggested, collide with the side and slide down.
  3. Bottom left (One2): This is clearly hitting the top of the platform, so it should collide and move to the left, as it currently, correctly does in 3.2.3 and as suggested.
  4. Bottom right (Two2): This is clearly hitting the side of the platform, so it should continue its trajectory. However, it should neither, as suggested, collide with the side and slide down, nor, as it currently, incorrectly does, bounce up half-way through the platform.

@Rhathe
Copy link
Contributor Author

Rhathe commented Oct 20, 2020

I disagree that both right cases should be expected to not collide with the platform. @bemyak's illustration shows a completely horizontal interaction with a one way platform, where hitting the side of the tile horizontally will stop the character's horizontal movement, which would be bad for most platformers. The real bug in the previous iteration of #42574 was that the collision margin was being affected by the velocity of the KinematicBody2D, so even only the top of the KienmaticBody2D and the top of the platform were interacting the margin was increased enough so that it seemed like there was a one way collision being detected.

This case however shows the bottom of each object hitting the top of the platform's set one way collision margin. Having an adjustable one way collision margin allows for leeway in jumping through a one way platform, so that it isn't strictly necessary for your character to be completely above the platform when trying to make a jump onto it. Also, these cases happen a lot when having your character run through tilemap platforms, as they will constantly be entering the corners of tiles as they run through other tiles.

@Rhathe
Copy link
Contributor Author

Rhathe commented Oct 20, 2020

Also have another case to add, in this one going straight down.

With one way collsion:
one_way

Without one way collision:
non_one_way

test_move_one_way_straight_down_corner.zip

@madmiraal
Copy link
Contributor

Also have another case to add, in this one going straight down.

The issue is not with the one-way collision shape, but with the normal shape, and is a duplicate of #23140 i.e. when there is no pixel overlap, there should be no collision.

@Rhathe
Copy link
Contributor Author

Rhathe commented Oct 23, 2020

Also have another case to add, in this one going straight down.

The issue is not with the one-way collision shape, but with the normal shape, and is a duplicate of #23140 i.e. when there is no pixel overlap, there should be no collision.

There should be overlap, zoom into the project and you'll see it overlapping if you adjust the y positioning. Also, the KinematicBody2D has an x position of 631.9 and an x extent of 32, so the left side should be at 599.9. The static body has an x position of 568 and an x extent of 32, so its right side should be 600. They should be overlapping once the KinematicBody2D falls down.

@Zireael07
Copy link
Contributor

@Rhathe: Floating point accuracy problems then, most likely.

@Rhathe
Copy link
Contributor Author

Rhathe commented Oct 23, 2020

@Rhathe: Floating point accuracy problems then, most likely.

It would be a rounding error that only affects one way collisions then. Removing one way collisions shows the KinematicBody2D stopping.

@madmiraal
Copy link
Contributor

The problem is that a collision is detected (#23140), but the collision normal is perpendicular to the direction of motion. With a normal shape the collision normal is irrelevant and the KinematicBody is stopped. With a one-way shape the collision normal is relevant, and a perpendicular collision is treated as pass through. This is the borderline case discussed in #42574, and why it needs to be pass-through is illustrated here.

@Rhathe
Copy link
Contributor Author

Rhathe commented Oct 25, 2020

#42574 (comment) shows a problem because the path has horizontal movement, and a collision stops the horizontal movement. This issue only has vertical movement, and with this a being a one way collision object, the collision normal should be on the axis of the one way way vector, i.e. vertically. This case is also dependent on the position and speed of the object, as adjusting the speed or y-position of the object in the test project affects whether or not this bug occurs. This means that there can be cases where a character does a small jump at the corner and lands in the same spot, but then jumps higher and falls right through the platform.

One fix for this is to never choose a collision normal that is perpendicular to the one way vector, which is the approach used in #38471.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants