[SOLVED] Glitchy elevator physics

Hello,

I am having problems with elevators that the player can ride in a project of mine.

When the elevator is moving, the player (and all other dynamic rigidbodies I place on the elevator) “bounce” every few frames, with the severity of the bounce clearly correlating with the speed of the elevator.

To confirm this, I have created a small example project, where one cube is kinematic and is moving up and down relatively fast using a simple sine function, while the other cube is a dynamic rigidbody resting on the first.

Here’s the project: PlayCanvas 3D HTML5 Game Engine
Here’s a short YouTube clip that displays the behaviour: PlayCanvas Elevator Glitch - YouTube

(The camera here is moving with the cube)

Please advise on how I can make elevator rides more smooth :slight_smile:

Best regards, Markus

Hi @MarkusA380,

You can set Restitution to 0.0 on the Dynamic body and that will absorb all the kinetic energy released on impact. Hopefully it will help get away with any bounces.

image

Unfortunately, that doesn’t fix it.
The “bounces” I am referring to aren’t coming from the two objects colliding, they occur out of nowhere while the object is resting on the moving elevator. The object “jumps” out of nowhere.
Check the demo project and see for yourself, I’ve updated the restitution parameters on both objects.

Ah, you mean the jitter when the two bodies touch. That’s more likely coming from the contact threshold between the two bodies, the kinematic body forces the dynamic to always be active and “colliding”.

@LeXXik any idea if there is a fix for that?

I’ve experienced this issue before. Whenever the browser drops a frame, it interferes with the physics. I can reliably recreate this with @MarkusA380’s project by resizing the window. Resizing causes the frame rate to jitter which causes the box to jump.

My understanding is that during the dropped frame, the box position doesn’t update, but then in the next physics frame, the boxes are inside one another, causing them to be pushed apart.

As a workaround, you could listen for collisionstart events on the elevator box. Whenever an object collides with it, you make the riding box a child of the elevator box and change its rigidy body type from dynamic to kinematic, that way it’ll move perfectly with the elevator. To get off the elevator, the riding box would have to fire some kind of event like jumping or moving, then you’d remove it as a child of the elevator and change its rigidbody state back to dynamic.

1 Like

Yes, so this is an elevator issue :slight_smile: Basically, a kinematic body pushing a dynamic one against it. I assume you have gravity there, so there is a force pushing the dynamic body down, while kinematic body is pushing it up. The jump happens when the two objects penetrate each other and the physics engine tries to “depenetrate” them.

One option would be to apply the same upward component of the elevator velocity (.linearVelocity.y) to the player body. This way, the player can still control the body left/right, but its upward velocity would match with the elevator.

Another option would be to make the player kinematic as well, and move it together with the elevator. If your player controller is using a dynamic body, then you won’t be able to control the player inside the elevator, unless you implement kinematic controls.

2 Likes

@LeXXik @Devortel @Leonidas

An update from my side.

Unfortunately none of your suggestions provided a solution.

Applying the velocity of the elevator to the player on it does not remove the issue, it only seems to make it a little less severe.

Making the player kinematic is not feasible as that interferes with other gameplay considerations.

But thanks to you all agreeing that moving kinematic bodies will always have that problem, I came up with a different solution that does work perfectly:

I make the elevator a dynamic rigidbody, set the mass relatively high compared to the player’s mass, and set the angular factors to zero, as well as a non-zero linear drag factor.

Then, in the script, I apply two forces to it on every update: One force that pushes the elevator towards the target position, with the magnitude getting larger the further away the elevator is (with an upper limit and a factor) and another force that simply negates gravity (Vec3.UP.mulScalar(this.entity.mass * 9.8)).

If I fine tune the upper force limit, the factor, and the linear drag factor, I get elevator movement that is snappy enough, and the player rides the elevator perfectly smooth. And I actually quite like that little bit of “jiggle” and “swing” that is the result of the elevator coming to a halt or the player stepping on it.

One could probably even come up with an algorithm that takes into account the elevators target velocity and it’s actual velocity and applies force changes accordingly, or even do PID tuning, to make the movement almost identical to just updating the position, but I didn’t need it.

4 Likes

If your gameplay allows it, then go for it :slight_smile: If you go with dynamic body for elevator, keep in mind that other bodies will affect it, as well as the player (if there is a jump mechanic, for example). Player can potentially get stuck in it. Using a dynamic body for the platform, you would want to set a dominance group on the elevator, which would make player body to treat it as kinematic, but it otherwise would be a dynamic body. Unfortunately, Ammo doesn’t support it.