Moving an object using math.lerp

I’m trying to move an object using lerp using the code below.
Here is the link: https://playcanvas.com/editor/scene/1134488

var Gamemanager = pc.createScript('gamemanager');

var shuffleObjects;
var chosenObject;
var cloneMaterial;

var timeElapsed;
var lerpDuration = 3;
var startValue=0;
var endValue=10;
var valueToLerp;

var move = (0,1,0);

// initialize code called once per entity
Gamemanager.prototype.initialize = function() {
    shuffleObjects = this.app.root.findByTag("SO");
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onSelect, this);
    this.timer = 0;
    this.isTimerActive = false;
};

Gamemanager.prototype.ColorChange = function(event){
    chosenObject = shuffleObjects[Math.floor(Math.random() * shuffleObjects.length)];
    cloneMaterial = chosenObject.model.meshInstances[0].material.clone();
    
    chosenObject.model.meshInstances[0].material = cloneMaterial;
    cloneMaterial.diffuse.set(1,1,0,1);
    cloneMaterial.update();
    this.isTimerActive = true;
};

// update code called every frame
Gamemanager.prototype.update = function(dt) {
    
    if(!this.isTimerActive)
        return;

    this.timer += dt;

    if (this.timer > 2) {
        cloneMaterial.diffuse.set(1,1,1,1);
        cloneMaterial.update();

        // Reset the timer
        this.timer = 0;
        this.isTimerActive = false;
        this.MoveObjects();
    } 
};

Gamemanager.prototype.MoveObjects = function(dt){
    
    //We reference the objects in the shuffleObjects array
    var object1 = shuffleObjects[0];
    var object2 = shuffleObjects[1];
    var object3 = shuffleObjects[2];
    
    //Then we create variables to store the initial positions of those objects
    var position1 = object1.getPosition();
    var position2 = object2.getPosition();
    var position3 = object3.getPosition();
    
    if (timeElapsed < lerpDuration)
    {
      valueToLerp = pc.math.lerp(position1, position3, timeElapsed / lerpDuration);
      timeElapsed += dt;
    }
    else 
    {
      valueToLerp = endValue;
    }
    
    object1.setPosition(valueToLerp);
    
    console.log("I have lerped to " + valueToLerp);
};

Testing the movement, I am using the lerp function, MoveObjects();, to move object1. I am trying to get object1 to go from position1 to position3 but it is moving somewhere else entirely and additionally, it isn’t moving smoothly as intended. Any help would be appreciated.

I see you use dt inside your MoveObjects function, but as far as I can see there is no delta time in this function right now.

You can replace your function start in your update function like this:

this.MoveObjects(dt);

Or maybe you can use your this.timer variable instead of dt:

timeElapsed += this.timer;

So I made the change you recommended to timeElapsed but the transition is still immediate instead of a transition over time. Additionally, the object is not moving to the desired location I believe

Maybe because timeElapsed could be wrong at the first time, because I can’t find where you define it to a value. So I think your else statement is executed instead of your if statement. Probably also the reason why you didn’t get an error about an undefined dt in your MoveObjects function because this line was never executed.

Your right, the else statement was being taken into effect. I set the value of timeElapsed to 0 in MoveObjects()

Gamemanager.prototype.MoveObjects = function(dt){
    
    timeElapsed = 0;
    
    //We reference the objects in the shuffleObjects array
    var object1 = shuffleObjects[0];
    var object2 = shuffleObjects[1];
    var object3 = shuffleObjects[2];
    
    //Then we create variables to store the initial positions of those objects
    var position1 = object1.getPosition();
    var position2 = object2.getPosition();
    var position3 = object3.getPosition();
    
    if (timeElapsed < lerpDuration)
    {
      timeElapsed += dt;
      valueToLerp = pc.math.lerp(position1, position3, timeElapsed / lerpDuration);
    }
    else 
    {
      valueToLerp = endValue;
    }
    
    object1.setPosition(valueToLerp);
    
    console.log("I have lerped to " + valueToLerp);
};

but now something odd is happening. Now the object is moving to:
[-2.177645444869995, 0.5, 0]NaN “According to the console”
which is its own position but it cant be seen.

Sorry, I’m really no expert in this, but I see I NaN in your console result and I like to know which variable is NaN exactly, because that’s probably the reason why you can’t see it anymore.

If I look at your script again, I don’t think your setup is going to work. You start your MoveObjects function only once in your update function and then it takes two seconds before you start it again. So the code inside this function is not executed constantly. Or is that what you want?

One thing to note here is that you won’t want to define timeElapsed in your MoveObjects() function. Since you are calling it every frame. It will always return 0. Consider defining it in you initialize function and then resetting it in your else function.

Also something to note, you are setting the object’s position as a number instead of a Vector3:

object1.setPosition(valueToLerp);

setPosition() requires 3 arguments for X, Y, and Z.

Final thought. If you just want to arbitrarily move the objects smoothly, have you considered just using the Playcanvas Tween Library? https://developer.playcanvas.com/en/tutorials/tweening/

It is much much more straightforward to work with than Lerps in the update function.

1 Like

Alright, after messing around a bit, I used tweening. Worked flawlessly and I have it up and running. Thank you everyone for all your contributions and sorry for the delayed reply.