-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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_with_snap steep slops problem #30310
Comments
I fixed it, but I'll leave this open because the fix requires a lot of GDscript code. Maybe it can be addressed easily otherwise. |
Can you please share how you fixed it? |
@Janders1800 Can you (or anyone else) still reproduce this bug in Godot 3.2.2 or any later release? If yes, please ensure that an up-to-date Minimal Reproduction Project (MRP) is included in this report (a MRP is a zipped Godot project with the minimal elements necessary to reliably trigger the bug). You can upload ZIP files in an issue comment with a drag and drop. |
Yes, it still happens on stable and on 3.2.3-rc3 The red wall is just a little bit rotated and the "player" gets launched on air (I suppose it should prevent it from climbing and force it to stay on floor), the green wall is completely vertical. |
I think You can mostly work around this by storing gravity velocity in a separate vector: gravity.y -= 9.8 * delta
var out_vel = move_and_slide_with_snap(vel + gravity, Vector3.DOWN, Vector3.UP, true)
if is_on_floor():
gravity = Vector3() This way the velocity due to gravity is not overridden. However, if you want to use this approach without snapping with More complicated workaround (just example, need to make it more robust) gravity.y -= 9.8 * delta
var start_pos = global_transform.origin
was_on_floor = is_on_floor()
var in_vel = player_vel + gravity
var out_vel = move_and_slide(in_vel, Vector3.UP, true)
if is_on_floor():
gravity = Vector3()
if was_on_floor and is_on_wall() and not is_on_floor() and out_vel.y > 0:
print("sliding up wall %d, first collision %s" % [Engine.get_physics_frames(), get_slide_collision(0).collider.name] )
self.global_transform.origin = start_pos
# TODO: can't assume first collision was with a wall, it might have been with the floor
# if it's not, then we have to iteratively advance our position and check the next collision
var wall_normal = get_slide_collision(0).normal
# we want to slide against the slopped wall as if it was a vertical wall
wall_normal.y = 0
wall_normal = wall_normal.normalized()
var new_slide = in_vel.slide(wall_normal)
new_slide.y = 0 + gravity.y
out_vel = move_and_slide(new_slide + gravity, Vector3.UP, true)
It can't do this internally without providing an extra argument to control this, because sliding up slanted walls is sometimes wanted behaviour, for example when you jump. Really, I think half the problem is the |
The problem happens with move_and_slide_with_snap. Your first solution doesn't work, the KinematicBody still gets launched. The problem in the function is the corruption of the Y axis, a simpler "fix" and a way to see the problem is using this code.
|
Godot version:
3.1.1
OS/device including version:
Zorin OS 12 Core (Ubuntu 16.04 LTS)
Issue description:
Wen a character moves to a slope too steep gets sent flying.
https://www.youtube.com/watch?v=sMNf2ZbLixQ
Steps to reproduce:
Move a KinematicBody with move_and_slide_with_snap to a steep slope.
The text was updated successfully, but these errors were encountered: