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

[Bullet] move_and_slide() causes jitter when colliding with corners between walls #32182

Open
Tracked by #45022
rptfrg opened this issue Sep 17, 2019 · 27 comments
Open
Tracked by #45022

Comments

@rptfrg
Copy link
Contributor

rptfrg commented Sep 17, 2019

Godot version:
3.1.1.stable.official

OS/device including version:
Linux / Fedora 30

Issue description:
move_and_slide() can cause a lot of jitter when KinematicBody collides with corners, or anything actually. (sometimes even with simple 90° corners)

You can observe this in pretty much every single project that uses move_and_slide(), including the FPS Tutorial from Godot documentation.

Notes:

  • Choosing GodotPhysics instead of Bullet may reduce the jitter, but it's still there and visible.
  • I haven't tested other move* functions.

Steps to reproduce:

  • Use move_and_slide().
  • Collide with some corners.

Minimal reproduction project:
godot-fps-master.zip

@rptfrg rptfrg changed the title move_and_slide() jitters in corners move_and_slide() causes jitter when colliding with corners Sep 17, 2019
@CptPotato
Copy link
Contributor

I can confirm this. This is the reason I switched to rigid body physics instead.

@kakoeimon
Copy link

Yes, this is a problem of capsule collision shape and sphere shape.
Never worked properly as far I remember.

For now you may consider using a cylinder or a box shape with a ray shape at the bottom with length of the maximum step height your character can climb.

@rptfrg
Copy link
Contributor Author

rptfrg commented Sep 19, 2019

I might be wrong, but I think jitter happens with a box shape too. (need to test this properly)

@rptfrg
Copy link
Contributor Author

rptfrg commented Sep 20, 2019

Yep, looks like it's happening with a box shape as well.

@narcissawright
Copy link

This is an issue for me as well. It is especially apparent in corners, but it also happens on walls. It doesn't seem to happen with simple convex shapes (like the grey rectangle in the attached gif).

problem

@DenisBelmondo
Copy link

DenisBelmondo commented Nov 30, 2019

Hello there, I can confirm that this still occurs in v3.2 Alpha 2. As a side note, calling move_and_slide*() on each separate axis can help mitigate the issue like so:

vel.x = move_and_slide_with_snap(Vector3(vel.x, 0.0, 0.0), snap, Vector3.UP, true, 1).x vel.y = move_and_slide_with_snap(Vector3(0.0, vel.y, 0.0), snap, Vector3.UP, true, 1).y vel.z = move_and_slide_with_snap(Vector3(0.0, 0.0, vel.z), snap, Vector3.UP, true, 1).z

As a side effect, the player unfortunately slides more slowly along walls and the jittering is only reduced when using Bullet instead of GodotPhysics using this method. It's also a pretty ugly hack.

As far as using move_and_slide() as it was intended went, I tested this with reasonably complex CSG constructs and level geometry I made in Blender and the jitter occurs only with these, further corroborating @narcissawright's claim that it never happens with convex shapes.

kinematicbody-plus-demo.zip

Here is a demonstration project that contains a simple CSG "garage" (the one immediately in front of the player in the scene). Moving into the corner produces jitter, but the “towers” behind the player, which are ordinary convex BoxShapes, do not produce jitter when moving into the corner.

@madmiraal
Copy link
Contributor

Duplicate of #29392?

@grevius5
Copy link

I confirm that this problem is still present in the 3.2rc1. @Calinou I think is a big problem, can we label it to be fixed in this milestone? Now if you have a simple 3d platform if you stay between 2 perfect aligned static platforms you will see this jittering and is frustrating to fix this issue.

@Calinou
Copy link
Member

Calinou commented Jan 19, 2020

@grevius5 We need more information before we can look into fixing this. It'd be worth testing whether this issue occurs in Godot 3.0 (and to a lesser extent, 2.1). If the bug doesn't occur in those versions, you could then look into bisecting the commit where the bug started appearing. This requires building the engine from source many times, but it should be entirely feasible.

In the meantime, I wonder if lawnjelly's smoothing-addon can be used to make the bug less noticeable.

@DenisBelmondo
Copy link

@Calinou you may be aware of this already (apologies if you are) but in #34596, @madmiraal provided some greatly needed specificity and cited this PR as the point at which the jittering started to appear in GodotPhysics and Bullet respectively. Do you think it could lend sufficient insight to the team?

@Poobslag
Copy link

I had this problem in a 3D platformer I was making. When a character (a kinematic body) ran along a set of boxes (static objects) 1 unit high, my character's Y-coordinate would oscillate between 1.06 and 1.10 as they crossed a corner. For a character 1 unit high, this results in the camera jittering up and down by 4% everytime they crossed a boundary.

I worked around the issue by scaling every object in my game by a factor of 1,000%. The jitter is still about 0.04, but when the objects are 10x bigger it's harder to notice.

@Poobslag
Copy link

Poobslag commented May 5, 2020

The small amount of jitter remaining after my previous fix (scaling everything up 1,000%) was still bothering me, so I came up with a second fix which removes the remaining jitter. Here's my new gravity function.

func _apply_gravity(delta: float) -> void:
    _velocity += Vector3.DOWN * 400.0 * delta

    # If acceleration via gravity makes our momentum something small like -6, there's a risk we won't actually collide
    # with the surface we're sitting on which causes causing an unpleasant jitter effect.
    if _velocity.y < 0.0 and _velocity.y > -10:
        _velocity.y = -10

The jitter occurs because the Y velocity is a small number like -6, which is too slow for Godot to detect a collision in some cases. Then the Y velocity increases to something faster like -13 and Godot detects a collision. It alternates between these states every other frame, causing the jitter

With this if statement I've added, the Y velocity is never a small number like -6, so Godot always detects a collision. You can adjust the '-10' value based on what works for you.

@Calinou Calinou added this to the 4.0 milestone May 6, 2020
@pouleyKetchoupp pouleyKetchoupp changed the title move_and_slide() causes jitter when colliding with corners [Bullet] move_and_slide() causes jitter when colliding with corners Jan 8, 2021
@pouleyKetchoupp
Copy link
Contributor

Can be still reproduced in 3.2.4 beta 5, but occurs only when using Bullet Physics (default settings). Switching to Godot Physics 3D fixes the issue.

@NicolasAubinet
Copy link

I just experienced this bug on Godot 3.3. Switching to Godot Physics 3D fixed it for me as well.

@VadimBigBoss
Copy link

Switching to Godot Physics 3D does NOT fix this issue.

@VadimBigBoss
Copy link

To solve this problem, there must be a way to check that we are in the corner.

@Art-Studio
Copy link

Art-Studio commented Aug 3, 2021

I found a simple way, the jitter is almost imperceptible if you give a slight tilt for a СollisionShape, for example along the x-axis rotation degrees 0.1 and change the vector in move_and_slide() or whatever you have from (X, 0, Z) to (X, -0.1, Z).

@pouleyKetchoupp
Copy link
Contributor

Switching to Godot Physics 3D does NOT fix this issue.

@VadimBigBoss Could you provide a minimal project to reproduce this issue with Godot Physics?

@discomrade
Copy link

discomrade commented Dec 2, 2021

Here is a very minimal 3D project that I believe reproduces this issue in both Bullet and GodotPhysics.
MiniCollisionTest.zip

Steps to Reproduce: (tested on 3.4.0)

  1. Select physics engine in Project Settings (Bullet or GodotPhysics) and test game
  2. Move forward until colliding with green wall (W or Up key).
  3. While continuing to push forwards against the wall, continuously hold right key to collide with blue wall (D or Right key). Notice effect.
  4. (optional) Repeat with other corners by forcing your character into them.
  5. (optional) Change collider to another shape. I reproduced the issue with a Sphere and a Cube, didn't test any others.

I believe this proves it is a major issue that affects both of the 3D engines, affects a commonly used feature and occurs during very basic usage.

note: I have made an equivalent project in Godot 4.0 (dev 2017590) and can reproduce the issue when Block on Wall is disabled.

@prominentdetail
Copy link
Contributor

prominentdetail commented Jan 30, 2022

I'm running into this issue too in 3.4.2, which causes is_on_floor() to become unreliable.. It's really annoying, as I'd rather not have to look for workarounds for something that should be simple.
floor

@Calinou
Copy link
Member

Calinou commented Jan 31, 2022

As mentioned in Shifty's Godot Character Movement Manifesto, the is_on_floor() part can be worked around by using a filter on the is_on_floor() check:

  • Unstable floor results make my 'is grounded' flag jitter
    • This seems to be down to the collision margin system
    • Use a rolling window (2-3 frames should be sufficient) that folds down to a single bool using OR to de-noise the floor check

In other words, create a function that wraps is_on_floor() and returns true if is_on_floor() returned true at least once in the last 3 physics frames (or 2, but it may not always suffice).

@Zireael07
Copy link
Contributor

@Calinou: Instead of cross-posting an external tutorial, this should be documented somewhere, and even better if a wrapper were provided out of the box since it fixes a known issue.

@prominentdetail
Copy link
Contributor

In other words, create a function that wraps is_on_floor() and returns true if is_on_floor() returned true at least once in the last 3 physics frames (or 2, but it may not always suffice).

Thanks! That solved that issue. That link also is interesting too. I'll have to try those other things if I try to do more complicated stuff in the future.

@fabriceci fabriceci modified the milestones: 4.0, 3.x Mar 26, 2022
@akien-mga akien-mga changed the title [Bullet] move_and_slide() causes jitter when colliding with corners [Bullet] move_and_slide() causes jitter when colliding with corners between walls May 19, 2022
@akien-mga
Copy link
Member

akien-mga commented May 19, 2022

For the record, I can confirm that this issue is still reproducible in the current 3.x branch (including with #56801 which fixed other similar issues, but not this one). I tested all three MRPs linked above to confirm that the bug is reproducible in 3.5 RC 1 and in #56801.

#32182 (comment)
#32182 (comment)
#32182 (comment)

It does seem to be Bullet-specific indeed, switching the above three MRPs to GodotPhysics solves this specific issue.

@IvailoBurov
Copy link

I found a simple way, the jitter is almost imperceptible if you give a slight tilt for a СollisionShape, for example along the x-axis rotation degrees 0.1 and change the vector in move_and_slide() or whatever you have from (X, 0, Z) to (X, -0.1, Z).

Changing Vector3.UP with Vector3(0, -0.1, 0) seem to solve issue for me (Godot 3.4.4)

@discomrade
Copy link

Here is a very minimal 3D project that I believe reproduces this issue in both Bullet and GodotPhysics.

note: I have made an equivalent project in Godot 4.0 (dev 2017590) and can reproduce the issue when Block on Wall is disabled.

I have tried recreating this in various Godot 4.0 alphas and betas (including the current beta 9) and the effect is far less noticeable than in Godot 3.x.

@MossFrog
Copy link

MossFrog commented Apr 14, 2023

This issue is still present in GDPhysics, the bottom collision point can oscillate between 2 values when using move_and_slide_with_snap() Godot Version 3.5.2 Stable, even on a flat surface after colliding with some corner or edge

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.