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 slides with move_and_collide #45004

Closed
Tracked by #45334
pouleyKetchoupp opened this issue Jan 8, 2021 · 5 comments · Fixed by #49901
Closed
Tracked by #45334

KinematicBody2D slides with move_and_collide #45004

pouleyKetchoupp opened this issue Jan 8, 2021 · 5 comments · Fixed by #49901

Comments

@pouleyKetchoupp
Copy link
Contributor

Godot version:
3.2.3 stable

OS/device including version:
Windows 10

Issue description:
Created from #18433 (comment) to have a separate issue for 2D.

KinematicBody2D slides down the slope when using move_and_collide. It can be reduced to a minimum setting to almost zero the safe margin in the kinematic body. But it's sliding anyway, only slower.

Steps to reproduce:

  1. Create KinematicBody2D with a CollisionShape2D
  2. Add a script to the KinematicBody2D:
extends KinematicBody2D

func _physics_process(delta):
	move_and_collide(Vector2(0, 98 * delta))
  1. Create a slope using StaticBody2D with a CollisionShape2D

Minimal reproduction project:
https://github.com/xphere/godot-testing/tree/slides-down-the-slope
(needs Debug/Visible Collision Shapes to be enabled)

@piratesephiroth
Copy link
Contributor

piratesephiroth commented Jan 8, 2021

Nice one!
I was about to post this exact issue.
Here's another simple project showcasing it:
move_and_collide-slide.zip

output.mp4

@Bhu1-V
Copy link
Contributor

Bhu1-V commented Jan 27, 2021

hello @pouleyKetchoupp, I want to work on this can u help me where to start

@pouleyKetchoupp
Copy link
Contributor Author

@Bhu1-V For sure! Your contribution would be welcome. At this point it's hard to tell how difficult it will be to solve, but it's not a problem for now. You can start with investigating the cause, share what you find and we'll find a good solution together if you need help.

Here are a some starters:

  • I would suggest to work on latest from the 3.2 branch first (it will be easier to run any test project from the community) but in the end the PR will be opened on master (the code should be mostly compatible).

  • You can start with checking KinematicBody2D::move_and_collide (of course) and also Space2DSW::test_body_motion where most of the logic for this motion is (collision tests are all calls to CollisionSolver2DSW::solve with different parameters).

  • test_body_motion goes through 3 phases:

  1. Free body if stuck by using collision test with extra margins
  2. Try to move the body without using the extra margins
  3. If it collides during the motion, check for rest information using extra margins
  • My guess would be that the sliding in move_and_collide occurs during phase 1, because it might push the body from the slope if it overlaps, in a direction that is not the direction of the motion (and then phase 2 moves it vertically and so on, which makes it slide along the slope). The first thing you can do is to run a simple case and debug it to confirm this is what happens.

  • If it's confirmed, I'm thinking about a potential way to fix it within KinematicBody2D::move_and_collide which can be simple, but I'm not sure it will work. You can check what move_and_slide does when stop_on_slope is used, and possibly use something similar to revert the sliding effect:

if (p_stop_on_slope) {
	if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) {
		Transform2D gt = get_global_transform();
		gt.elements[2] -= collision.travel.slide(up_direction);
		set_global_transform(gt);
		return Vector2();
	}
}

Note: It would have to be adapted to move_and_collide, not done when move_and_collide is called from move_and_slide and applied along the body motion instead of up_direction.

If that doesn't work or the problem comes from something else we'll figure something out :)

@piratesephiroth
Copy link
Contributor

piratesephiroth commented Feb 13, 2021

One curious detail is that it makes the KinematicBody2D slide again when detaching from the colliding obstacle.
I updated my sample project above (and video) to display the body's positions.

@piratesephiroth
Copy link
Contributor

piratesephiroth commented Jun 16, 2021

After observing it more carefully, I see that the problem comes from the way the kinematic body recovers from being stuck.

image

You see that when the kinematic body moves to the right and enters the slope, it's always ejected out pretty much following the slope's normal.

If the process is repeated multiple times, the body will appear to slowly slide up along the slope.

image

So maybe the solution to make the body always move, collide and then stop is to make it always recover toward the position it was at before the collision, so that the undesired part of the movement gets undone properly?

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

Successfully merging a pull request may close this issue.

4 participants