Mathf.Lerp never gets there

Hi,

I want to lerp from 0 to 1 then back from 1 to 0, this is my code -

// Only look at the player if within lookdistance
	if(distanceToPlayer < lookdistance){
		theLookAtPosition = player.position;
    	ikLootAt.solver.IKPosition = theLookAtPosition;
		lerpWieghtUp();
		ikLootAt.solver.IKPositionWeight = lookWeight;
	}else if(distanceToPlayer > lookdistance){
		lerpWieghtdown();
		ikLootAt.solver.IKPositionWeight = lookWeight;
	}
}

function lerpWieghtUp(){

	while(lookWeight < 1.0f){
		lookWeight = Mathf.Lerp(lookWeight,1.0f,Time.deltaTime*lookSmoother);
		yield;
	}

}

function lerpWieghtdown(){

	while(lookWeight > 0.0f){
		lookWeight = Mathf.Lerp(lookWeight,0.0f,Time.deltaTime*lookSmoother);
		yield;
	}

}

But lookWeight never reaches 0 or 1 so the while loop still keep going, how can I hit 0 and 1 with lerp?

Another way I can do this is -

// Only look at the player if within lookdistance
	if(distanceToPlayer < lookdistance){
		theLookAtPosition = player.position;
    	ikLootAt.solver.IKPosition = theLookAtPosition;
		lerpWieghtUp();
		ikLootAt.solver.IKPositionWeight = lookWeight;
	}else if(distanceToPlayer > lookdistance){
		lerpWieghtdown();
		ikLootAt.solver.IKPositionWeight = lookWeight;
	}
}

function lerpWieghtUp(){

	while( lookWeight < 1.0f ){
		lookWeight =+ 0.01f;
		yield;
	}
}

function lerpWieghtdown(){

	while( lookWeight > 0.0f){
		lookWeight =- 0.01f;
		yield;
	}
}

But it looks false because of the sudden stoping at the ends, not gradually like lerp, any help would be appreciated, thanks.

Well, the problem here is that you shouldn’t be using just the Time.deltaTime in the lerp.

Because here is how Lerp works:
“Interpolates between a and b by t. t is clamped between 0 and 1.”

So for the lerp to actually “get there” you need to maintain a counter

function lerpWieghtUp(duration : float){
     var counter : float = 0.0f;
     while(counter < 1.0f){
         lookWeight = Mathf.Lerp(lookWeight,1.0f, counter);

         counter += Time.deltaTime / duration;
         yield;
     }
     lookWeight = 1.0f;
 }

and if you want it to look smoother you can use Mathf.SmoothStep

function lerpWieghtUp(duration : float){
    var counter : float = 0.0f;
    while(counter < 1.0f){
        lookWeight = Mathf.Lerp(lookWeight, 1.0f, 
            Mathf.SmoothStep(0.0f, 1.0f, counter));
        
        counter += Time.deltaTime / duration;
        yield;
    }
    lookWeight = 1.0f;
}

Duration here let’s you specify how long should the animation take.

What i do, when using Lerp is add one IF statement which finish the Lerp when it gets realy close to it’s target, cuz when finishing, the Lerp is slowing down and yes, sometimes it allmost never reach it’s target value.

So what you can do is this:

function lerpWieghtUp(){
 
    while(lookWeight < 1.0f){
       lookWeight = Mathf.Lerp(lookWeight,1.0f,Time.deltaTime*lookSmoother);
       if (lookWeight >= 0.95)
            lookWeight = 1;
       yield;
    }
 
}
 
function lerpWieghtdown(){
 
    while(lookWeight > 0.0f){
       lookWeight = Mathf.Lerp(lookWeight,0.0f,Time.deltaTime*lookSmoother);
       if (lookWeight <= 0.05)
           lookWeight = 0;
       yield;
    }

I am not testing the code in Unity, so i’m not sure if you have to put the If statement before or after the yield… Hope it helps :slight_smile:

If 0.05 makes your object to snap too noticeable, you can decrease it to 0.025…