godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.14k stars 21.19k forks source link

move_and_slide - slope collision issue #20593

Closed piratesephiroth closed 3 years ago

piratesephiroth commented 6 years ago

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:

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 commented 6 years ago

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 commented 6 years ago

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.

piratesephiroth commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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

piratesephiroth commented 6 years ago

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 commented 3 years ago

solved by #50495