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

KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled #31981

Open
Tracked by #45333
Miziziziz opened this issue Sep 5, 2019 · 15 comments

Comments

@Miziziziz
Copy link

Miziziziz commented Sep 5, 2019


Bugsquad edit: This issue has been confirmed several times already. No need to confirm it further.


Godot version: 3.1.1

OS/device including version: Ubuntu 19.04

Issue description:
According to the documentation, setting infinite inertia to false on a KinematicBody should make so it cannot move RigidBodies. However, when I disable it, I'm still able to move rigidbodies

Minimal reproduction project:
WASD movement
space to jump
mouse look
exit to escape

try pushing or jumping on the trucks, one uses VehicleBody and the other Rigidbody.
If you check the player script you can uncomment and use move_and_slide, move_and_slide_and_snap, and move_and_collide. All will move the trucks.

clustertruckclone.zip

@madmiraal
Copy link
Contributor

I think this is a duplicate of #25857, but this is a better description of the problem.

@Crystalwarrior
Copy link

Any workarounds for this issue?

@rzetterberg
Copy link

I have the same problem, but it manifests itself a bit differently.

I have a FPS setup with a KinematicBody for the player and an attached script that uses move_and_slide (infinite_inertia set to False) to move the player.

When the player collides with the VehicleBody at first, it is not moved, but if the player jumps on top of the VehicleBody it starts to move as if infinite_inertia is set to true.

I have noticed the same thing happening when I have a setup with 2 VehicleBody's connected with a ConeTwistJoint (a car and a trailer) and the player passes between the car and the trailer, basically walking through the joint. When that happens it's like infinite_inertia is set to True, just like when jumping on top of one of the VehicleBody's.

I have this problem on Godot 3.2.3 on Linux.

@ghost
Copy link

ghost commented Dec 13, 2020

I have the same problem (Godot 3.2.3, Windows).

KinematicBodies cannot affect RigidBodies that are sleeping, however they can move RigidBodies already affected by physics. I am yet to find a proper workaround or alternative solution :(

@pouleyKetchoupp
Copy link
Contributor

For info, this is a Bullet specific issue.

I've tested the MRP on 3.2.3 stable:
Still happens with Bullet, but doesn't occur when switching 3D physics to Godot Physics in project settings.

@teshst
Copy link

teshst commented Dec 28, 2020

I have the same issue in Godot 3.2.3 Mono switching it from DEFAULT physics to Godot Physics in project settings as mentioned above fixes the issue for me.

Edit: Increasing safe margin seems to fix a lot of the issues

@pouleyKetchoupp pouleyKetchoupp changed the title KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled [Bullet] KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled Jan 15, 2021
@e344fde6bf
Copy link
Contributor

e344fde6bf commented Mar 27, 2021

I've been investigating this, and the problem is that bullet backend doesn't correctly leave the collision margin between bodies when it moves a kinematic body. So when rigid bodies are processed, the kinematic body will be inside it's collision margin causing the rigid body to depenetrate and get pushed away from the kinematic body.

One of the sources of this bug is this if statement which is accessing an uninitialised variable. That if statement looks like a copy and paste error, and removing it fixes it for this one case. I haven't checked all the other cases yet. Edit: that's incorrect. However, I think the general cause of this bug is still that the kinematic body gets too close to the rigid body.

Edit2: there seems to be two parts to this problem:

  • The main cause is the Bullet backend doesn't use the kinematic safe_margin. This is a Godot property that seems to leave a gap between the kinematic body and what it is colliding with. Godot physics seems to behave the same way as bullet if you set the safe margin to 0: PhysicsServer.body_set_kinematic_safe_margin(get_rid(), 0.0).
  • Bullet backend uses different collision detection algorithms for rigid and kinematic bodies in some cases which use the margin property differently. This is a much minor cause of this issue, mainly effecting box-to-box collisions and is more of a separate issue.

but doesn't occur when switching 3D physics to Godot Physics in project settings.

This still seems to happen when using the Godot backend, it just is happening at a much slower rate. Godot seems to be using collision margins wrong too. Here's the project that I used to test this with which is a bit simpler than the one OP provided: infinite-inertia-bug.zip

Using Godot physics notice that the cube is still pushed, and the sphere doesn't leave the collision margin between it and the cube.

godot-no-collision-margin.mp4

Using bullet backend with the fixed I mentioned: in this particular case happens to work because it leaves a gap between the two bodies:

bullet-correct-collision-margin.mp4

@e344fde6bf
Copy link
Contributor

e344fde6bf commented Mar 27, 2021

One potential workaround to this bug which works in both bullet and Godot physics, is to use collision exceptions/layers. One-way collision exceptions/layers aren't a thing at the moment, but you can get the same effect by doing something like this:

remove_collision_exception_with(rigid_body)
move_and_slide(..., infinite_inertia=false)
add_collision_exception_with(rigid_body)

then your kinematic body will never be able to move the rigid body unless you manual apply forces to it. This is slightly different than the just using infinite_inertia=false since a moving rigid body will effectively push away the kinematic body unless you manually apply a force to stop it.

@pouleyKetchoupp
Copy link
Contributor

@e344fde6bf Thanks for investigating! Concerning Godot Physics, I can confirm the issue does occur at a slow rate.

From what I've seen, it's due to CollisionSolverSW::solve_distance detecting no collision in some cases where it should, which allows the kinematic body to slightly overlap with the rigid body after the motion is applied. It seems to come from errors in the GJK-EPA algorithm (maybe because of using no margin).

Apart from checking the gjk-epa algorithm itself, it might help to apply a little margin to the distance checks used for defining the safe and unsafe distances in SpaceSW::test_body_motion to compensate for these errors, but that needs a bit more investigation and testing.

@pouleyKetchoupp pouleyKetchoupp changed the title [Bullet] KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled Apr 5, 2021
@JotaFaD
Copy link

JotaFaD commented Apr 27, 2021

Still present in godot 3.3-stable

@RemotelyHuman
Copy link

Still Present in Godot v3.3.3 stable

@Calinou Calinou changed the title KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled [Bullet] KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled Sep 18, 2021
@pouleyKetchoupp pouleyKetchoupp changed the title [Bullet] KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled KinematicBody still able to move Rigidbodies and VehicleBodies when infinite inertia disabled Sep 30, 2021
@Zacxalot
Copy link
Contributor

Please forgive me if I get anything wrong here, I'm new here but I want to help.

I built the master branch earlier and tested this problem using a CharacterBody3D which I think is the new name for KinematicBody. With CharacterBody3D, the move_and_slide function accepts no arguments, and there are no properties related to infinite_inertia anymore.

Sliding the CharacterBody into a RigidBody in the way pictured below resulted in what I would say is the behaviour we expected from KinematicBody with infinite_inertia set to false. After making contact with the RigidBody cube, the sphere didn't move to the right any significant amount. I think any movement that did occur in the sphere and the cube were maybe just random jitter as I disabled can sleep on the cube.

image

Hope this is helpful in some way. Please let me know if you need me to try any other scenarios.

Project Zip:
BrokenTest.zip

@pouleyKetchoupp
Copy link
Contributor

With CharacterBody3D, the move_and_slide function accepts no arguments, and there are no properties related to infinite_inertia anymore.

In 4.0, infinite_inertia is not needed anymore because one-way collision layer checks are supported now (see godotengine/godot-proposals#2775).

So now you have more options:

  • Leave both collision layers to 1, in this case both will collide with each other. It's the equivalent of infinite_inertia = false in 3.x, and it has the same issues (the character and the rigid body can push each other depending on the situation).

  • Set the character body to collision layer 2, in this case it will be ignored by the rigid body so the character will stop. It's the equivalent of infinite_inertia = false, and the rigid body will also push the character. It works well for cases like characters vs. vehicles.

(this is the equivalent to @e344fde6bf's workaround described in #31981 (comment))

  • Set the rigid body to collision layer 2, in this case it will be ignored by the character body which will not stop and will push the rigid body. It replaces infinite_inertia = true and behaves the same as in 3.x.

@AttackButton

This comment was marked as off-topic.

@DimaKiva
Copy link

Godot 3.5.1 It worked for me after I set the safe margin to >= 0.06 in KinematicBody!

Снимок экрана от 2023-02-14 02-06-00

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