Problem moving rigidbody with linearVelocity


#1

Hello, I am moving a rigidbody by setting the linearVelocity. The problem is the body is slowing by time.
How it starts:
https://gyazo.com/c6749f4ad3a1b1c48cc44dc3840f5aad
After 5 minutes of movement:
https://gyazo.com/6ef9539ff6b8a9aef24d373da97f93f0
As you can see the speed is decreasing. This is affecting forces too (as well as gravity). It’s like if the mass is slowly dropping to 0. Also, when the speed reaches 0, the body “struggle” or “teleport” for a second and the speed is back to normal which is really strange.
I can’t find anything abnormal in my code.
Here is the script that is attached to my rigidbody. (based of the first person movement script):

var Test = pc.createScript('test');
Test.prototype.initialize = function() {
    this.force = new pc.Vec3();
    this._createCamera();
    this.power = 4;
};
Test.prototype.update = function(dt) {
    var force = this.force;
    var app = this.app;
    var forward = this.camera.forward;
    var right = this.camera.right;
    var x = 0;
    var z = 0;
    if (app.keyboard.isPressed(pc.KEY_A) || app.keyboard.isPressed(pc.KEY_Q)) {
        x -= right.x;
        z -= right.z;
    }
    if (app.keyboard.isPressed(pc.KEY_D)) {
        x += right.x;
        z += right.z;
    }
    if (app.keyboard.isPressed(pc.KEY_W)) {
        x += forward.x;
        z += forward.z;
    }
    if (app.keyboard.isPressed(pc.KEY_S)) {
        x -= forward.x;
        z -= forward.z;
    }
    this.entity.rigidbody.teleport(this.entity.getPosition()); //I am putting this line because I will need it later to add angles.
    force.set(x, 0, z).normalize().scale(this.power);
    force.y = this.entity.rigidbody.linearVelocity.y;
    this.entity.rigidbody.linearVelocity = force;
};
Test.prototype._createCamera = function () {
    //I didn't add the camera component because I just need this for directions.
    this.camera = new pc.Entity();
    this.entity.addChild(this.camera);
};

The question is why is this happening. What’s causing it. (I’m aware that there are other solutions for movement)
Note: the static ground friction is 1. The body friction is 0.3. I don’t think the friction is causing this, because I tried with jumping (the player is not always on the ground) and this is still happening.


#2

Does it still happen when you don’t have this line?


#3

I just tested. No, it doesn’t happen when I remove that line. o_o
I also tried putting it after setting the velocity but not working.
I don’t understand how can that line cause such behaviour. Any idea? :thinking:
I need it to rotate the rigidbody, what can I do?


#4

To rotate the rigid body, you can do this -

this.entity.rigidbody.applyTorque(x, y, z);


#5

Teleporting the object would most likely reset all the forces/etc back to 0 or perhaps to floating point imprecision, perhaps it is teleporting it into the floor? It’s just not good to do every frame.

Set rotation velocity? Does the rigidbody actually need to rotate?


#6

Well, yes I need to rotate it. I will use the rotation velocity but…

This doesn’t make sense, it’s called teleport, why would it reset forces or velocity. And even if it does, I am setting the velocity right after teleporting, so the velocity shouldn’t change?
Also, the speed is back to normal again after it reaches 0. That’s really strange. I need a fix because I need to use teleport for other reasons and not just rotation. For example I would need it if I make real time multiplayer to update positions from the server.
I feel it’s more like a bug than a normal behaviour.


#7

Teleporting effectively breaks the physics simulation as you are saying be here one frame and somewhere else the other. The simulation world can’t really handle that type of situation well. Imagine if you teleported yourself into the floor in the real world, what would actually happen?

Looking at the teleport function, it doesn’t actually reset the velocity (personally I think this is odd that it doesn’t but it does leave the choice to the developer).

It’s possible that the teleportation is causing extra collisions especially with floating point imprecision. Can you share the project?

Arguably, using the teleport to set the position on the client is a bandaid. Normally, the physics simulation (for things that matter to the game (eg. players,) is done on the server and the updated transformations are sent to the clients who won’t be simulating physics locally. Or physics is done on both the client and the server and if there is a drift between the two, the client corrects.

Teleportation really shouldn’t be done every frame.


#8

The project was just a test and has nothing more than what I put in the topic. The Y coordinate is not changing so I basically think it’s not a collision problem :thinking:
Note that the body keep slowing even if you apply some up impulse from time to time (jumps)
I can stop using the teleportation every frame, but I am worried if it still happen and it would just take more time to slow down. I haven’t tested that yet.
Here is the link: https://playcanvas.com/editor/project/593043
you won’t notice the speed slowing until at least 5 minutes.


#9

Actually, it does with the physics simulation. If you print out the Y position every frame without the teleport code, you can see it moves slightly up when you are moving. With the teleport, it can teleport it to a Y position where it sticks into the floor.


#10

If I can’t use the teleport, then there should be another function for rotation. How do you expect me to rotate the rigidbody then? I tried syncEntityToBody but it has the same effect as the teleport. I cannot use the angularVelocity (as well as applyTorque) because I need to rotate by a known angle.


#11

Angular velocity can work here depending on how/why you are rotating the body. Eg set the rotational velocity for one frame only before resetting it to 0.

Another possibility is to separate the visual mesh from the rigidbody so you can rotate the mesh freely.

Can you give more context of the project? There may be another solution pending on the features of the project etc.