Tweening with linear easing still seems to slowly increase duration of tween. How do I fix this?

Hello! I can’t figure out why my tweening seems to increase duration bit by bit even though I am using linear easing. I want to have my entity move to one side and flip 180 degrees in three seconds.

This is my code for rotation.

Rotation.prototype.update = function(dt) {
  this.timer += dt;

    if(this.timer > 3){
        this.entity.translateLocal(0,0,0);
        this.entity.rotateLocal(0,180,0);
        this.timer = 0;
    }
};

The tweening only uses the basic code provided by PlayCanvas with these settings changed.

TweenPosition.attributes.add('duration', {type: 'number', default: 3});
TweenPosition.attributes.add('easing', {type: 'string', default: 'Linear'});
TweenPosition.attributes.add('delay', {type: 'number', default: 0});
TweenPosition.attributes.add('loop', {type: 'boolean', default: true});
TweenPosition.attributes.add('yoyo', {type: 'boolean', default: true});

This is how I changed the position

 this.tween = this.entity.tween(this.entity.getLocalPosition())
        .to(new pc.Vec3(this.entity.getLocalPosition().x + 4, this.entity.getLocalPosition().y, 0), this.duration, pc[this.easing])
        .delay(this.delay)
        .loop(this.loop)
        .yoyo(this.yoyo);

For the first few seconds, the rotations align with the tween but after a few more seconds, the tween’s duration seems longer, so the rotation happens earlier than the object moving back to its original position.

Hi @milkycrumb and welcome,

Are you able to share a repro project to take a look? That may help in identifying this issue.

Hi! Here’s a link to the published project. You can see that over time, the caterpillar moves back to its initial position before rotating instead of at the same time.

Welcome to PlayCanvas!

So it is hard to be able to quickly look into larger projects. It takes a lot of time to debug and understand someone’s code. Especially the published links with minified code. Next time, please create an empty project with a minimal setup that shows your problem. You could add a simple box and rotate it with Tween, just like you do in your game. This way it is easier for us to see where the issue is.

As for your actual problem, I think the issue is that:

  1. You start the tween for 3 seconds
  2. The timer ends and you reset position to zero
  3. Tween, almost reaching the target position can no longer stop, since the position is now zero and far from target position, so it just continues tweening.

You can make the timer different from tween duration. Or change the logic that it resets the position to zero on Tween finish callback.

1 Like

Thank you for your response! I replicated the issue here. Them going out of synch is very subtle but increases over time.

Also, how do I reset the position to zero? I tried looking it up but I mostly found people who didn’t want their tween to reset :sweat_smile:

Ah, you are actually not setting the position to zero with setLocalPosition(0, 0, 0), but moving it by zero meters translateLocal(0, 0, 0) (which doesn’t do anything actually). I will look at your example later, once I have some time, unless someone looks at it sooner.

Thanks for your response ! I just ended up using a timer method with translateLocal and translateRotate.

var Rotation = pc.createScript('rotation');
var cDirection = 0;

// initialize code called once per entity
Rotation.prototype.initialize = function() {
    this.entity.sprite.play('angry');
    this.timer = 0;
    cDirection = this.timer;
};

// update code called every frame
Rotation.prototype.update = function(dt) {
  this.timer += dt;

    if(this.timer > 2){
        this.entity.rotateLocal(0,180,0);
        this.timer = 0;
    }
    if (this.timer !=0 ){
        if (cDirection == 1){
            this.entity.translateLocal(-0.08,0,0);
            this.entity.setPosition(new pc.Vec3(this.entity.getPosition().x, this.entity.getPosition().y, this.entity.getPosition().z));
        }

        if (cDirection == 0){
            this.entity.translateLocal(0.08,0,0);
            this.entity.setPosition(new pc.Vec3(this.entity.getPosition().x, this.entity.getPosition().y, this.entity.getPosition().z));
        }
    }

};

I would still appreciate it if you mentioned how to reset tweens though ! Thank you!

1 Like

I’ve been playing your test project from before but I’ve not seen it go out of sync between the tween and rotation.

How long should I be playing it for? I’ve kept this running for 5-10mins