- Home /
Still confused on lerps...
I thought I had lerps figured out. Trying to make a simple scale lerp script. Object should lerp to a certain scale, and then lerp back down.
What happens is there is no lerp, the object just instantly is max scale, and then it doesn't lerp back down!
#pragma strict
var pulseUpSpeed : float = 0.2;
var pulseDownSpeed : float = 0.2;
var pulse : boolean = false;
var pulseDown : boolean = false;
private var targetScale: Vector3;
private var atRestScale: Vector3;
var currentScale: Vector3;
function Start ()
{
atRestScale = Vector3 (40, 35, 0);
targetScale = Vector3 (68, 59, 0);
}
function Update ()
{
currentScale = transform.localScale;
if (pulse)
{
PulseUp ();
}
if (pulseDown)
{
PulseDown ();
}
}
function PulseUp ()
{
transform.localScale = Vector3.Lerp (atRestScale, targetScale, Time.deltaTime * pulseUpSpeed);
yield WaitForSeconds ( pulseUpSpeed );
pulse = false;
pulseDown = true;
}
function PulseDown ()
{
transform.localScale = Vector3.Lerp (targetScale, atRestScale, Time.deltaTime * pulseUpSpeed);
yield WaitForSeconds ( pulseUpSpeed );
pulseDown = false;
}
Any help would be appreciated
You you don't have pulse = true anywhere.
Also, calling in a routine with yield WaitForSeconds may not work, or at least it may not be smooth.
pulse = true will be the command another script will trigger. it also allows me for testing purposes, to simply check the pulse box to perform the action I want.
I'll try moving the yield's into the update function to see if that solves the problem.
edit moving the yield's into function Update didn't work. It coughed out this error;
Script error: Update() can not be a coroutine.
You can not Lerp in a one hit action, if thats what you are thinking. Pulse must become true frequently.
Pulse is true for the duration of the lerp I thought. That's why the yield waitforseconds (lerp time); then it becomes false.
You need to keep hitting Lerp to extract the point value while modifying t. It won't 'complete' in 1 call.
Answer by robertbu · Oct 09, 2013 at 07:26 PM
You have a couple of issues here. They are common issues with questions on this list, but I rarely see them combined. Let me start by giving you some code that I think does you wanted. It is a partial rewrite of your code. I might approach the problem differently:
#pragma strict
var pulseUpSpeed : float = 10;
var pulseDownSpeed : float = 10;
var pulse : boolean = true;
var pulseDown : boolean = false;
private var targetScale: Vector3;
private var atRestScale: Vector3;
function Start ()
{
atRestScale = Vector3 (40, 35, 0);
targetScale = Vector3 (68, 59, 0);
}
function Update ()
{
if (pulse)
{
transform.localScale = Vector3.MoveTowards (transform.localScale, targetScale, Time.deltaTime * pulseUpSpeed);
if (transform.localScale == targetScale)
{
pulse = false;
pulseDown = true;
}
}
else if (pulseDown)
{
transform.localScale = Vector3.MoveTowards (transform.localScale, atRestScale, Time.deltaTime * pulseDownSpeed);
if (transform.localScale == atRestScale)
{
pulse = true;
pulseDown = false;
}
}
}
One issue with your original code is the 'yield'. A 'yield' means the processing stops at that point and control returns to the calling method (Update() in this case), but that processing will continue from the 'yield' at some future time. Typically you would call a function with a 'yield' (usually referred to as a coroutine) once and then allow it to do its work over a number of frames. You are calling it at each Update(). This produces a new coroutine each time the function is called. So you have many coroutines stacked up. Assuming your app is running at 60 fps, you stack up 12 coroutines before the first one finishes (given your value of 0.2 for pulse up speed). It is possible to write this code as coroutines, but this is not the way to approach it.
The second issue is Lerp(). The traditional use of Lerp() is to have the last parameter change over time from 0.0 to 1.0. That is you create a timer or increment a value so that over time the value covers this range. A non-traditional use, is to have the last parameter be some small value, but to update the starting point each frame. Your code does neither. Note if you update the starting point each frame, the result is an eased effect. For your application, I've instead use MoveTowards. This function can be though of as using speed rather than time to drive it and will produce a non-eased movement over the range without requiring the construction of a timer.
Holy shit! Thank you! I never heard of the syntax "$$anonymous$$oveTowards", I will have to check into this to use it appropriatly, ins$$anonymous$$d of trying to have lerp solve all my problems!
Thanks again Rob!