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

move_and_slide - slope collision issue #20593

Closed
piratesephiroth opened this issue Jul 30, 2018 · 7 comments
Closed

move_and_slide - slope collision issue #20593

piratesephiroth opened this issue Jul 30, 2018 · 7 comments

Comments

@piratesephiroth
Copy link
Contributor

Godot version:
3.0.x

OS/device including version:
All

Issue description:
move_and_slide does not work properly on 2D platformers with slanted terrain.
If the player character colides with a slope fast enough it will bounce/slide a little. This interferes with horizontal movement and it of course is not the expected behaviour in most situations.

This also happens in some cases when landing/jumping on slopes,

Imgur

I know it's just the player being ejected out of the solid ceiling according to the surface's normal but it doesn't feel natural. move_and_slide can detect floor, ceiling and walls so it should also be able to use predetermined directions for the ejection instead of the ones calculated according to the colliding surface's' normal.

So, regardless of the surface angle:

  • Ceilings should always eject the player downwards (no effect on x speed);
  • Floors should always eject the player upwards (no effect on x speed);
  • Walls should always eject the player sideways (no effect on y speed);

Steps to reproduce:
Use move_and_slide to collide with a slope in a 2D platformer.

Minimal reproduction project:
The issue is quite self-explanatory so a project isn't really necesssary but here's the platformer scene from the kinematic2D page on the documentation.
using_kinematic2d.zip

@eon-s
Copy link
Contributor

eon-s commented Jul 30, 2018

I think is caused by the default safe margin, separation is big and pushes the body in an angle making the effect of a sliding, reduce the margin to 0.001 and try again.

@reduz
Copy link
Member

reduz commented Jul 30, 2018

This is not a bug, and it really depends on the game and control. There is not an universal way to do this, though I see the following could be improved:

  1. Could set a threshold for sliding against the ceiling
  2. You can easily implement your own motion logic using move_and_collide instead of move_and_slide, but there are not good enough examples about this.

Godot 3.1 also will add a few more tools to make all this easier and straightforward, so I will leave this open as enhancement and documentation tags.

@reduz reduz modified the milestone: 3.1 Jul 30, 2018
@piratesephiroth piratesephiroth changed the title move_and_collide - slope collision issue move_and_slide - slope collision issue Jul 30, 2018
@piratesephiroth
Copy link
Contributor Author

piratesephiroth commented Jul 30, 2018

I think is caused by the default safe margin, separation is big and pushes the body in an angle making the effect of a sliding, reduce the margin to 0.001 and try again.

A smaller safe margin will only reduce the effect. Also safe margins that low might cause issues with the sliding on slopes.

This is not a bug, and it really depends on the game and control

Yeah, just like ceiling and floor don't apply to all games.
This current behaviour probably fits a game where physics must be more accurate, like a Sonic the Hedgehog- style platformer. It's awkward for something simpler like Megaman or Castlevania.

Could set a threshold for sliding against the ceiling

Threshold? I don't really see how to do that.

You can easily implement your own motion logic using move_and_collide instead of move_and_slide, but there are not good enough examples about this.

Yeah, for the ceiling collision I just added a test with move_and_collide whenever the player isn't on the floor and Y speed is positive. If it would collide with a slanted ceiling then the Y speed is immediatly zeroed.

I know I can do everything with move_and_collide however I prefer to use move_and_slide because not only it's simpler but also most of the calculations are performed internally instead of being interpreted by the scripting engine so it should also be a little faster.

Perhaps the solution is to use what's coming in 3.1, raycast shapes. Pointing 2 rays, one up and one down, should solve this issue for good. I'll take a look and report back.

@piratesephiroth
Copy link
Contributor Author

Well, a single ray shape works fine however it's not enough for a decent collision check
Adding more rays only results in weird behaviour and this error

Condition ' p_normal.is_normalized() == false ' is true. returned: Vector2() in C Source: core\math
math_2d.cpp:173 C Function: Vector2::slide

It's still experimental so that was sort of expected, heh

@eon-s
Copy link
Contributor

eon-s commented Aug 3, 2018

I'm a bit confused, the issue is about slide or collide?

@piratesephiroth
Copy link
Contributor Author

I'm a bit confused, the issue is about slide or collide?

it's about move_and_slide. I opened this issue right before I went to bed so I only caught the mistake in the title on the next day, heh

@piratesephiroth
Copy link
Contributor Author

solved by #50495

@akien-mga akien-mga added this to the 3.4 milestone Jul 27, 2021
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

4 participants