JoltPhysics
JoltPhysics copied to clipboard
Jitter when CharacterVirtual is standing on a diagonally downwards moving platform
Hi Jorrit, there's an issue when a CharacterVirtual is standing on a platform that is moving downwards but also sideways. See the following video:
https://github.com/user-attachments/assets/09d93b68-c998-4552-b910-fdf03bc35207
Note that everything works fine as the platform moves up, but when moving down the avatar jitters sideways relative to the ground.
Patch to repro is to change line 630 of Samples\Tests\Character\CharacterBaseTest.cpp to
mBodyInterface->MoveKinematic(mReversingVerticallyMovingBody, pos + Vec3(0, mReversingVerticallyMovingVelocity * 1.0f * inParams.mDeltaTime, mReversingVerticallyMovingVelocity * inParams.mDeltaTime), cReversingVerticallyMovingOrientation, inParams.mDeltaTime);
Cheers, Nick
It is caused by PhysicsSystem::Update and CharacterVirtual::Update being called at different times. The physics update will move the platform away from the character. This means that at the beginning of the character update the world state is:
The red line indicates the platform velocity, which is what the character will inherit:
https://github.com/jrouwe/JoltPhysics/blob/c1bdc5aee24ba08359b539efc5dc3b23f8e3bdbc/Samples/Tests/Character/CharacterVirtualTest.cpp#L144
It will currently, unconditionally, add gravity to that velocity (green):
https://github.com/jrouwe/JoltPhysics/blob/c1bdc5aee24ba08359b539efc5dc3b23f8e3bdbc/Samples/Tests/Character/CharacterVirtualTest.cpp#L163
So the resulting velocity will be the blue arrow. This means that the character will hit the platform slightly to the right of where it used to be standing and shift a little bit to the right.
I can fix this particular case by moving the gravity calculation in the else clause like this:
if (...)
{
// Assume velocity of ground when on ground
new_velocity = ground_velocity;
// Jump
if (inJump && moving_towards_ground)
new_velocity += sJumpSpeed * mCharacter->GetUp();
}
else
{
new_velocity = current_vertical_velocity;
// Gravity
new_velocity += (character_up_rotation * mPhysicsSystem->GetGravity()) * inDeltaTime;
}
which has the disadvantage that it takes 1 frame longer before gravity will kick in after the platform changes direction. This will make the scene look like this:
https://github.com/user-attachments/assets/38ee5016-bd1a-4d24-9999-c6a395c7ba18
You can probably add some extra logic to detect platform velocity changes to get rid of the hops, but I really consider this 'game code' as everybody can make their own choices how this should behave.
Thanks for the reply. Will try it out soon.
Unfortunately that approach has its own problems - the character becoming unsupported from the ground in some situations on moving (and rotating) platforms.
Are you using the 'stick to floor' feature?
yeah
Are you able to create a repro in the Samples app? The mRotatingAndTranslatingBody body in the samples moves and rotates at the same time and doesn't seem to have issues.
Here's an example of problems when gravity is only applied with character is not supported: https://youtu.be/UCLnK43sRJA
It seems like something to do with interacting with complicated mesh geometry. I don't really want to try and make a repro in the samples app.