bevy_rapier
bevy_rapier copied to clipboard
Strange KinematicCharacterControllerOutput behaviour
Sorry for the vague title, I'm really not sure how to word this succinctly.
I'm trying to make a basic 2D character controller with gravity and collisions. For this, I decided to use the provided KinematicCharacterController and Velocity components to handle collisions and movement respectively.
I don't know if it's something I've done wrong, but grounded keeps flickering between true and false every couple of frames if I reset linvel.y while not grounded, even when the player collider is nowhere near the ground collider. If you wait for it to fall through, it no longer flickers.
I've put together a gist that illustrates the problem. If you Check the console you'll find something like this repeated over and over:
Grounded: true Velocity: [0, 0]
Grounded: false Velocity: [0, 0]
Grounded: false Velocity: [0, -9.81]
Grounded: false Velocity: [0, -19.62]
Grounded: false Velocity: [0, -29.429998]
Grounded: true Velocity: [0, -39.239998]
If you remove Line 47 (the line resetting linvel.y), the flickering stops, but the colliders still pass through each other instead of colliding.
Extra notes:
- I've noticed that if I set
linvel.yto a negative value (down) instead of resetting it to zero,groundedstops flickering when the player reaches the ground, but then slowly sinks down into it. - The issue also happens when using a fixed timestep, if that helps.
- The issue still happens when using the
Ccdcomponent. KinematicCharacterController.snap_to_grounddoes nothing to help.
Am I doing something wrong? I thought something like setting the Y velocity to 0 when on the floor would be a relatively simple thing to do.
Facing the exact same issue here. Anyone looking into this?
I see the same thing in 3D as well. The only force I'm applying to the entity is gravity downward, but it flips between true/false for grounded every frame even though the entity's Transform is unchanged:
grounded KinematicCharacterControllerOutput { grounded: false, desired_translation: Vec3(0.0, 0.0, 0.0), effective_translation: Vec3(0.0, 0.0, 0.0), collisions: [] }
character NOT grounded pos Vec3(-10.0, 0.0, 16.47299)
grounded KinematicCharacterControllerOutput { grounded: true, desired_translation: Vec3(0.0, 0.0, -10.0), effective_translation: Vec3(0.0, 0.0, 0.0), collisions: [CharacterCollision { entity: 48v0, character_translation: Vec3(-10.0, 0.0, 16.47299), character_rotation: Quat(0.0, 0.0, 0.0, 1.0), translation_applied: Vec3(0.0, 0.0, 0.0), translation_remaining: Vec3(0.0, 0.0, -10.0), toi: Toi { toi: 0.69120264, witness1: Vec3(-10.162319, -0.40132886, 15.116304), witness2: Vec3(-0.1623106, -0.40130597, -0.6654587), normal1: Vec3(0.26897535, 0.6691901, 0.6927026), normal2: Vec3(-0.26897535, -0.6691901, -0.6927026), status: Converged } }] }
character grounded pos Vec3(-10.0, 0.0, 16.47299)
The only difference is it has some collisions when grounded = true, but I don't apply any forces and the entity's position is unchanged