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 behaviour bugs with Bullet physics engine #18624

Closed
SaracenOne opened this issue May 5, 2018 · 30 comments
Closed

KinematicBody behaviour bugs with Bullet physics engine #18624

SaracenOne opened this issue May 5, 2018 · 30 comments
Assignees
Milestone

Comments

@SaracenOne
Copy link
Member

Godot version:
af9a620

OS/device including version:
Windows 10

Issue description:
I had previously created an extension to Godot's KinematicBody node which includes features like ramp and stairs traversal, and which seemed to run exactly as intended under the old Godot physics system, but under the new Bullet physics, a variety of issues have appeared. These issues can be most obviously observed by testing with the provide test project I have linked to and trying it with both physics engines. The code which previously allowed seamless traversal over a variety of difficult surfaces now no longer works as intended. It should be worth noted however that not ALL of these issues which now appear were present in the last stable release of Godot, even when using the Bullet physics engine, and this can also be tested by running the provided project with a stable release of the engine. However, the stable release STILL does have issues with the Bullet physics engine which are just less obvious. These can often be observed by attempting to ascend the ramp from the side or attempting to land on the crack in the wall. @AndreaCatania has expressed an interest in trying to debug this issue further, but all help would be appreciated.

Steps to reproduce:
Simply test the provided project under the latest build of Godot and run it with both the old GodotPhysics engine and the new Bullet physics engine. If you want to test this under the previous stable release (I've only tested this with the Steam build assuming this is the latest stable build), use the 'extended_kinematic_body' godot_3_stable branch or download the stable zip file project.

Minimal reproduction project:
https://github.com/SaracenOne/godot_extended_kinematic_body_testbed
godot_extended_kinematic_body_testbed_bleeding_edge.zip
godot_extended_kinematic_body_testbed_stable.zip

@AndreaCatania
Copy link
Contributor

I've checked it and I can confirm that it's different.

The problem apparently seems the separation process that makes the body step back when on a slope. But it should work as godot does.

I'm investigating more I let you know

@SaracenOne
Copy link
Member Author

@AndreaCatania Thanks! Hopefully we can figure this thing out soon :)

@AndreaCatania
Copy link
Contributor

This zip file is a simplified version of your project, where basically execute just: move_and_slide
godot_extended_kinematic_body_testbed_stable.zip

The algorithm has a separation process and if you provide a movement like this: Vector3(0, -10, 0) the result will be something like this:
untitled

The separation process basically takes the normal vector between the capsule and the downhill and separate, then will be executed the movement and the result is the sliding along downhill

When you exec it using Godot it doesn't slide down, and I can't understand why... I'll make another function similar to move_and_slide that allow the kinbody to remain still on downhill

@SaracenOne
Copy link
Member Author

@AndreaCatania I think I have some more information on this now. It seems that the main cause of the issue is that the Bullet physics KinematicBody move_and_collide method doesn't work as intended; in the original it would get stuck on a wall and then you would use the collision normal's dot product to slide around with multiple passes. Here, the method just results in sliding around regardless, which would explain the newly introduced quirky behavior when it comes to navigating slopes and stairs.

Not sure how to fix it though, and its unfortunate because I really want to migrate to it now due to issues I'm not encountering in the old physics engine :(

@AndreaCatania
Copy link
Contributor

Well the sliding algorithm is the same, I didn't touch it.. The difference between physics is another and I already explained it above.

Also the move_and_slide function must take care of what you are doing here, check this: #20908

@SaracenOne
Copy link
Member Author

@AndreaCatania I'm still having trouble following exactly what's going though in relations to the failures of my movement implementation :\ At the moment, your modified project seems to be broken on the latest build, so I can't really test for comparison, but I'd be willing to guess that it still wouldn't behave exactly like my original implementation since while a lot of it might seem redundant, it's still very carefully hand-tweaked to account for a wide variety of difficult geometry the player might encounter.

Among other things, it uses the move_and_collide method to essentially ground the controller when attempting to traverse a slope. Because the move_and_collide method in Bullet also slides the controller off uneven walls and floors (unintended functionality?) this would explain why going up a valid slope or staircase is now slower, and going down is faster, whereas with the old physics engine your movement speed would be unaffected. This bug/undocumented functionality seems to be part of the original Bullet implementation of the move_and_collide method. The part of the code which actually causes the different movement speed on the stairs is located here.

https://github.com/SaracenOne/extended_kinematic_body/blob/master/extended_kinematic_body.gd#L141

I just pushed a change here which also accounts for another difference of the physics solver where it is more liberal in regards to detecting whether or not it has touched a collider by testing the length of the remainder, but what I would point you attention to is the attempt to push the player controller down as far as it can downwards by the step_height. While in the original physics engine, it would only push the player downwards, in the Bullet implementations, if the player is on a slope or stairs, this method will also attempt to slide them downwards too, which is not how this method is supposed to behave.

On another note, while I'm not sure what relation this might have, looking through the code, it would seem possible that the safe_margin is not being taken into account during the KinematicBody collision check either, but I can't say what kind of affect that might be having at the moment.

@SaracenOne
Copy link
Member Author

@AndreaCatania Bit more information as to the root of these behavior differences. I think the unwanted sliding is caused by the first phase of the test_body_motion

{ /// Phase one - multi shapes depenetration using margin
, but still haven't figured out what the best way would be to fix it.

@SaracenOne
Copy link
Member Author

SaracenOne commented Aug 13, 2018

@AndreaCatania I've also just updated the testbed project so that it should be compatible with the latest build too.
https://github.com/SaracenOne/extended_kinematic_body
godot_extended_kinematic_body_testbed_bleeding_edge_2.zip

@AndreaCatania
Copy link
Contributor

Fixed in master branch #8c435a3 , now you can set new boolean parameter stop_on_slope so prevent kinematic character to sliding on slopes.

@SaracenOne
Copy link
Member Author

@AndreaCatania I just tested it, but this still doesn't solve my specific problem at all. As I said, I want to stop the move_and_collide, not the move_and_slide method, from sliding, which it didn't do under the older physics engine but it does under this.

@SaracenOne
Copy link
Member Author

SaracenOne commented Aug 26, 2018

godot_move_and_collide.zip
This project may help explain my issue a bit more simply. If you test this under both physics engines, you can see that the move_and_collide method from the Bullet engine has sliding behavior when it collides with objects, whereas with the older physics engine it (kind of) gets stuck on a surface. It still moves a little, but in my own approach to physics, I relied on that ability to move the kinematic body up and down without it sliding all around to handle certain forms of difficult to navigate terrain. Basically, I need a way to have a KinematicBody collide with a surface without it automatically sliding.

@AndreaCatania
Copy link
Contributor

AndreaCatania commented Aug 26, 2018

I can confirm that it's different and I'm sorry but after (more than) one hour of debugging I think that the algorithm that I've implemented is correct. The sliding that you register is due to depenetration process and from what I can saw is correct that behave like this if you call it each tick.

Probably ther's something more that godot does to "prevent (IDK if is the right word)" the sliding... but by following my current understanding of algorithm I'm not able to make this behave like godot... I'm really sorry for it.

@SaracenOne
Copy link
Member Author

@AndreaCatania I would expect that there must be another way of doing a separate depenetration process specifically for this? While the approach might be correct in the algorithmic sense, it's kind of goes against the Godot way the current Godot setup handles character physics, doesn't behave how the API describes it, and partially renders the need for a separate move_and_slide method somewhat redundant. I'd say it's probably premature to deprecate the old physics engine just yet until some sort of solution is found out because this change in behavior can cause a lot of problems, and even renders some more complex approaches to physics like my implementation, currently completely impossible.

I'm going to ping @reduz, to see if he has any thoughts on solving this problem.

@AndreaCatania
Copy link
Contributor

I agree on fact that should be found where is the inconsistency.

And apart that your final result can be achieved in a more easy way in this moment, you don't need anymore create your own move_and_slide function.

@SaracenOne
Copy link
Member Author

@AndreaCatania While I know that the move_and_slide function has a lot more added to it recently, I still doubt it's anywhere near as robust as my own implementation. A lot of time was spent tweaking it.

@AndreaCatania
Copy link
Contributor

You spent a lot of time on it because you try to prevent the sliding applied of move_and_slide, so it's kind of work around. Instead the last implementation of move_and_slide solve it from the begin without hacks.

Also the fact that is not robust should be proved, in order to give us the possibility to improve it.

@SaracenOne
Copy link
Member Author

@AndreaCatania, no that wasn't the only thing. It had a lot of handling for things like seamlessly traversing stairs up and down, ect., in fact, to simplify things, it even uses move_and_slide method as part of its main integration phases, but used single dimensional integrations for testing space up and down, hence why in my demo, you'll see the character slip off the stairs as they attempt to traverse them, among other things, when using the Bullet physics engine. The sliding thing wasn't even given a second thought when writing the initial implementation since it wasn't really even relevant to what I was doing.

There was a lot of neat physics features my implementation was able to handle that the builtin solution still can't. Some of those features probably could be brought in, and some of them already have in the 2D kinematic body, but the approach is still different. Trust me, I went through like three or four complete rewrites trying to perfect character physics.

@SaracenOne
Copy link
Member Author

Oh, I should also probably mention that my implementation is very similar to PhyX's inbuilt character controller.

@piratesephiroth
Copy link
Contributor

piratesephiroth commented Aug 30, 2018

BTW "stop_on_slope'" seems completely broken on 2D. It prevents from sliding UP slopes too instead of only DOWN, lol

@AndreaCatania
Copy link
Contributor

AndreaCatania commented Aug 30, 2018

@piratesephiroth You should open another issue for it, also are you sure to apply correctly the floor direction? in 2d UP is negative.

@piratesephiroth
Copy link
Contributor

piratesephiroth commented Aug 30, 2018

@AndreaCatania yeah I already created it: #21595

Everything is fine with the script.

@AndreaCatania
Copy link
Contributor

@SaracenOne Rechecked it and seems to me that Godot algorithm slide even if it's way slower then bullet. So I think that there isn't a bug. Also I advice you to implement from the scratch an API that does exactly what you need in order to achieve the wanted result.

@AndreaCatania
Copy link
Contributor

AndreaCatania commented Sep 7, 2018

#21838

I've exposed the internal functions used by move_and_collide function body_test_motion_light and body_test_motion_depenetrate.

Now you can use body_test_motion_light that perform only the motion test, this will fix your problem.

Physics.body_test_motion_light( ... )

@SaracenOne
Copy link
Member Author

@AndreaCatania I'll give this a try and see if it works. Thanks! 👍

@AndreaCatania
Copy link
Contributor

I did it using new APIs
ezgif com-video-to-gif

@piratesephiroth
Copy link
Contributor

piratesephiroth commented Sep 8, 2018

Please take a look at #21595 too.
I did a quick hack (#21653) to restore the normal slope sliding and also the awkward brief freezing that ocasionally happens before colliding with the floor.
However raycast shapes are still weird (not that they worked perfectly before but after your modifications they are weirder, making the kinematic body jitter on the floor)

@akien-mga akien-mga added this to the 3.1 milestone Sep 10, 2018
@akien-mga
Copy link
Member

What's the current status on this issue in the master branch?

@AndreaCatania
Copy link
Contributor

This is what I did to fix this problem: #21838 but was not accepted.

The move_and_slide algorithm works correctly I've tested many times

@reduz
Copy link
Member

reduz commented Feb 14, 2019

This should work in Bullet the same way as in Godot physics, so kicking to 3.2 for now as we have not a fix.

@akien-mga
Copy link
Member

Tested in the current master branch, Bullet and GodotPhysics seem to behave the same now (both slide), so I guess this is fixed, even if not the way that was originally requested.

I'll close for now, but if you think there's still changes to do for both backends, it might be worth tracking in a new, summarized issue. Alternatively we can reopen this one if that would be better.

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

6 participants