Weird behaviour on 120Hz monitors and some 120Hz phones

We are working on a project using physics and we discovered that the rigibidbody.teleport was having some issues on 120Hz refresh rate screens. The rigidbody that we are teleporting is running twice slower than normal and when we teleport it to a specific location it’s different from the location we intended to teleport to.

I unfortunately cannot share the project at this time because it’s not officially open yet (will be next monday)

I am pretty sure the problems comes from the monitor refresh rate because when I change the monitor settings to 60Hz everything works fine.

I searched around if we can easily cap the fps to 60 within playcanvas but couldn’t find any good solutions. And I am not even sure if this would fix the problem or not.

The weird things is that I tried a bunch of other website using physics and telport functions but I couldn’t see similar behaviour.

I cannot share the entire project but I can show you the code with the teleporting function:

PlayerController.prototype.update = function(dt) {
    
    // raycast
    if(this.mouseDown) this.doRayCast(this.mousePosition);        

    if (this.direction.lengthSq() > 0) {
        // Move in the direction at a set speed
        let d = this.playerSpeed * dt;
        if(this.globalScript.state.isDebug && this.app.keyboard.isPressed(pc.KEY_SHIFT)) d = this.debugSpeed * dt;
        if(this.isOnAuto) d = this.autoSpeed * dt;
        let newPosition = PlayerController.newPosition;
       
        newPosition.copy(this.direction).scale(d);
        newPosition.add(this.entity.getPosition());

        this.entity.rigidbody.teleport(newPosition);

        this.distanceToTravel -= d;

        // udpate foot print
        this.updateFootPrints();

        // play foot step
        if(!this.isMoving) {
            this.soundManager.play('footstep');
            this.enableFootPrints(true);
            this.isMoving = true;

            // change to run
            if(this.playerModel.anim.baseLayer.activeState != 'run') this.playerModel.anim.setTrigger('run');
            
            // timer
            this.timerOn = false;
        }
        
        // If we have reached our destination, clamp the position and reset the direction
        if (this.distanceToTravel <= 0) {
            this.entity.rigidbody.teleport(newPosition);           
            this.direction.set(0, 0, 0);

            // stop foot step
            if(this.isMoving) {                
                this.soundManager.stop('footstep');
                this.enableFootPrints(false);
                this.isMoving = false;
                
                // change to idle
                if(this.playerModel.anim.baseLayer.activeState != 'idle') this.playerModel.anim.setTrigger('idle');
                
                // timer
                this.timerOn = true;
                this.time = 0 ;

                // zone trigger callback
                if(this.targetIndex >= 0) {
                    if(this.targetIndex >= 100) { // for floor interaction
                        this.app.fire('playerDoneMovingOnDance');
                        this.needCallback = -1;
                    }
                    else {
                        this.app.fire('playerDoneMoving', this.targetIndex);
                        this.needCallback = -1;
                    }
                }
            }
        }

Any help appreciated!

Thanks in advance

Hi @creativelab! I’ve also experienced similar problems on my 144hz screen device. The issue has been reported and hopefully something will be done about it soon.

1 Like

Oh my god, how can I thank you enough? The quick fix on the github comment saved my day in a way you cannot imagine!

Looking forward to share the result of 2 months of hard work on monday!

Thank you so much @Albertos !!!

1 Like