Can't keep same speed depending on the framerate

Hi,

This is my first message here.
I am finalizing my first PlayCanvas project.

I have a few questions, the first is a bit of an odd one… I’ve been scratching my head about it.

tl;dr:

I have a script on my character, that will teleport him in a direction every frame.
The direction is a normalized vector scaled by the delta parametter sent by the update.

Simple but it works. Eccept that… I don’t get the same speed depending on the frame rate.
The highest the framerate, the slower the speed.
Speed on device running at 120FRS > Speed on device running at 90FPS > speed at 60FPS…

I have checked the sum of deltas to check if there was some time lost somewhere between updates, but no… So really have no idea where the issue might come from.

Does this kind of issue ring a bell to you ?
What could possibly be the cause in your opinion ?

Thanks !

Show us the piece of code that calculates the distance the entity should travel and how you move the entity.

Hi LeXXik.

Yeah, i figured you would ask that…

The thing is my project is too complex to easily simplify and I cannot share it…
So all I can give you are some samples of the code:

PlayerMovement.prototype.update = function (dt) {

        PlayerMovement.testPosition = this.position.clone().add(this.direction.clone().mulScalar(this.speed * dt));

        // I test if there is ground at this position
        var result = this.app.systems.rigidbody.raycastFirst(
            PlayerMovement.testPosition.clone().add(new pc.Vec3(0, 2, 0)),
            PlayerMovement.testPosition.clone().add(new pc.Vec3(0, -2, 0)),
            {
                filterCollisionGroup: pc.BODYGROUP_USER_3,
                filterCollisionMask: pc.BODYGROUP_USER_4
            }
        );

        if (result) this.position.copy(result.point);

       this.entity.rigidbody.teleport(this.position.x, this.position.y, this.position.z, 0, this.rotY, 0);
}

I really don’t think anything is wrong with that, I’ve reviewed this code in detail.
I was looking for some idea of where I should dig… If anybody ever experiences that?

I was gonna post when suddenly… an epiphany

Something I just noticed, and I think this might be the issue:
Why would colision / rigid body alter the teleport, even so slightly, when there are no obstacles?

I have different collision groups in my project.
The floor colides with the raycast as seen in my code.

And the charcater uses a different group that can collide with obstacles (such as walls), but not the floor.

I take back the position at the begining of every loop to benefit from the the collisions feedback, before calculating where I should teleport on this update (code seed up there).

When I teleport in an area free of obstacles, I can assert that my character will not collide with anything, so the rigid body should teleport exactly where I tell him to.
And yet, my character is teleported slightly less far than I ask for.
Enough so that it can make a big difference cumulatively, especially when the framerate is higher.

When I disable the collision of my character, although I run trhough any obstacles, I have no issues of slowing down. My character runs the same, fluidly, whatever the framerate.

I hope this is clear…
Do you have any idea of how I could handle this issue?

Thanks.

Its hard to say what is happening without debugging. I don’t see why teleporting into a collision mesh would have a different result on different refresh rates. Ammo always updates at fixed interval of 1/60s. Even if your monitor is updating at 1/240, the physics world will still update at 1/60. You are not using forces/impulses, just teleporting, so it shouldn’t matter anyway.

Anyhow, I wouldn’t use teleport for anything than just respawning objects. Especially not for moving objects like you do, or like some tutorials here show. It breaks some collision math and can produce incorrect inertia under some conditions.

I would use one of those:

  1. Use kinematic body with a shapecast and program own logic to prevent clipping.
  2. Use dynamic body and move it with forces/impulses.
  3. Use a physics engine that supports kinematic character controller natively.

Thank you for the time you took replying.

I tried impulses and forces, they don’t fit my needs.
Too complicated to fine tune, I need more control.

Ammo always updates at fixed interval of 1/60s.

This has to be my issue.
Some teleport must be ignored or something.

But I think I can work around this.
Is there any event when ammo is triggered ?
Is there any way tro trigger Ammo every frame ? Or at least change the period ?

Thanks.

No, there isn’t.

You could change the update event, which updates Ammo. You could also use the same event for your own “fixed update” method in your script. Something like this:
https://playcanvas.com/project/914980/overview/physics-fixed-update

You can change the fixed timestep Ammo runs at by changing:

app.systems.rigidbody.fixedTimeStep = 1/144;

app.systems.rigidbody.fixedTimeStep = 1/144;

That did it !

And its not even an issue with perfs (I only have one dynamic object)

Thanks a lot !

I would expect this to still not work on 144+ Hz screens now.

For something like this, I would have a visual entity that interpolates between the physics updates or is predictive of the physics updates.