-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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 does not collide with new position of a moved KinematicBody - can tunnel through #30481
Comments
Worth noting: if I move the movement of one of these from _physics_process() to _process(), they collide, so it seems the position update is deferred. Is there some way to force this update immediately after moving a kinematic body? |
the example code is not correct i think. new code:
and it works fine on what you are doing is setting |
The purpose of the example is to do 1 step, and one step only. The end result is that the kinematic bodies are inside of each other at the end of the frame (as seen by the screenshot). If you move the platform up slightly so that it collides on the first frame, it'll still exhibit the issue, even with your change. |
alrighty, my bad. afaik, if you don't want bodies inside each other, a RigidBody can/should be used. they will get updated and not tunnel through |
RigidBody doesn't offer the level of control that I need. I need to be able to step multiple times in a frame with move_and_collide(). |
I've partially fixed this by directly updating the position of the body on the physics server: Unfortunately, it's a two-stage problem. The body position is updated, however, the broadphase is not, so collision still does not happen (unless you "trick" it into having a larger broadphase by having additional collision shapes on the kinematic body. Now I just need to find a way to force the broadphase to update, but I'm concerned about potential performance issues with that. |
Ok, I've got a little hack to work around around this for now. Not sure what the performance implications are to always updating the broadphase and transform on every kinematic move, so I just did this, for now:
And in GDScript, I use this after moving objects that can interact with each other: That body_set_state function calls set_transform. Down side is, this gets done twice, since the transforms are set at the end of the physics frame, and also the broadphase aabbs are updated as well, so the aabb gets updated 3 times instead of once, but at least it fixes my particular case of an elevator platform and player moving through each other. A better solution might be to just update the transform and aabb's whenever a move happens. Again, not sure what performance implications are of that, but it would be more robust. This is just a bit of a hack to make my game shippable. |
Another issue I'm running into now is the depenetration / recover_from_penetration() logic seems to push the character to the side when I move it down enough to collide with the platform again. The depenetration logic is the source of a lot of bugs (slowly sliding down slopes, etc). I've tried disabling it in SpaceBullet::test_body_motion and just using the sweep, which actually gets me better results in general, except for the fact that the character often sticks when moving parallel to a surface (which is likely the whole purpose of the margin and depenetration in the first place). |
Does KinematicBody use continuous collision detection internally? Since KinematicBody is just a RigidBody in Kinematic mode internally, why are collision signals and some relevant methods from rigidbody not bound with classdb ? |
Still valid in 3.2.4 beta4 |
sounds like this proposal discusses the mentioned issue: godotengine/godot-proposals#2332 |
My current workaround for this is to use In godot 3.x, this only works on bullet, and does not work on godot physics. I do not know why. |
In my case (3.5.1, bullet physics, with two kinematic bodies moving toward one another), it was sufficient to just use An aspect of my case that was confusing to me was how directional it was, even when the end result should theoretically have been the same. The body moving first was always effectively inside where the area the second (larger) one would end up covering, but the issue only happened when they were moving in opposite directions (i.e. toward each other). |
I tried this on 4.0 beta 17 (godot physics only), it did not work. Tried both |
Godot 4 uses godot physics IIRC so that makes sense. |
Godot 4 uses Godot physics, yes. |
Godot version: 3.1.1
OS/device including version: Windows 8.1
Issue description:
If two kinematic bodies move toward each other using move_and_collide() in the same frame, they can intersect, or even tunnel through, since the collision does not seem to take into account the updated position of the KinematicBody that moved first.
Steps to reproduce:
Put one kinematic body above the other with space in between. Move the bottom kinematic body up toward the top body using move_and_collide(). In the same physics process frame, move the top body down below the new position of the bottom body. Note that the top body can partially (or even completely, if the movement is large enough) pass through the bottom body without registering a collision.
Minimal reproduction project:
test_broken_collision1.zip
The text was updated successfully, but these errors were encountered: