idanarye / bevy-tnua

A floating character controller for Bevy
https://crates.io/crates/bevy-tnua
Apache License 2.0
180 stars 12 forks source link

Character does small "midair jump" when it tries to jump over a platform and comes a little short #14

Closed idanarye closed 1 year ago

idanarye commented 1 year ago

This is from my game, Gardening Gun, which uses Tnua (I've edited the level a bit so that the character will only interact with a single collider):

https://user-images.githubusercontent.com/1149255/231580031-8794e62c-9db0-4211-87e0-1b92533617dd.mp4

The character is not supposed to be able to do that extra airjump to get on top of the platform.

idanarye commented 1 year ago

This replicates in the 3D example:

https://user-images.githubusercontent.com/1149255/232314409-3287115c-30b9-42d8-bf96-97aa64fdcab2.mp4

And when I add debug rendering:

https://user-images.githubusercontent.com/1149255/232314605-9bf889f4-1dbf-4ee2-a2a6-7b131a39086a.mp4

WTF?

idanarye commented 1 year ago

This definitely has something to do with the sensor shape. When I reduce the flat-underfit radius from 0.49 to 0.4 I get a much smaller climb effect:

https://user-images.githubusercontent.com/1149255/232316248-fedc3e8c-8b9b-44d4-b2aa-8ce615fdd3df.mp4

Whereas with radius 0.3 I get no climb effect at all.

idanarye commented 1 year ago

Thinking that maybe the Rapier transforms were not synchronized with the Bevy transforms when I perform the cast, I tried adding this to update_proximity_sensors_system:

if let Some(rigid_body) = rapier_context.entity2body().get(&owner_entity).and_then(|h| rapier_context.bodies.get(*h)) {
    let rigid_body_translation = Vec3::from_slice(rigid_body.translation().as_slice());
    assert_eq!(rigid_body_translation, transform.translation());
}
if let Some(collider) = rapier_context.entity2collider().get(&owner_entity).and_then(|h| rapier_context.colliders.get(*h)) {
    let collider_translation = Vec3::from_slice(collider.translation().as_slice());
    assert_eq!(collider_translation, transform.translation());
}

But it did not panic.

idanarye commented 1 year ago

It looks like the character's collider gets pushed a bit into the other collider, which breaks stuff. To solve this, I'm going to have to check for contacts when filtering the entities.