- Home /
Vector3.Lerp completing before t = 1?
Hello all, I think I broke Vector3.Lerp (either that, or I'm doing something very wrong)
I want to set up a simple camera path to zoom in, by lerping its transform. I want to have a modifiable total duration, for testing purposes, so I set up this script to test it. The problem is that the lerp completes way before the t parameter reaches 1, and I have no idea why. This is the code I'm using, which by all accounts should be working:
if(camZoom){
timeInZoom = Time.time-zoomStartTime;
timeClamped = timeInZoom/zoomDur;
transform.position = Vector3.Lerp(startTransform.position,endTransform.position,timeClamped);
transform.eulerAngles = Vector3.Lerp(startTransform.eulerAngles,endTransform.eulerAngles,timeClamped);
if(yPrev==transform.position.y){
Debug.Break();
}
}
yPrev = transform.position.y;
When I use a desired total zoom duration (zoomDur variable) of 8 sec, the Debug.Break() kicks in at 2.1 seconds in the lerp (timeClamp shows a value of 0.26 in the Inspector at that point). As you can see, I'm using the timeClamped var to control the Lerp, and for the life of me I can't figure out why it completes when its t parameter is still 0.26! I have confirmed that the camera has actually reached its target Transform at that point, so the Vector3.Lerp works properly, but in a quarter of its desired time.
Any help please?
I see nothing on the surface wrong with this code unless startTransform is your transform. If it is, you are mixing two different Lerp uses since 'startTransform.position' will be updated each frame. When varying 't' between 0 and 1, both the start and end positions need to remain constant.
Hi robertbu,
No, startTransform is recorded once when the lerp begins, and is the camera's Transform at the beginning of the lerp; after that point it is never reassigned a new value.
Answer by robertbu · Dec 16, 2013 at 04:05 PM
Variables can refer to their data either by reference or by value. Transforms are referred to 'by reference'. The above code moves the camera, and 'startTransform' gets assigned the transform of the camera. Since you have a reference, each time the camera position changes, 'startTransform.position' will change.
Vector3s are by value. If you look in the scripting reference you will see the word 'struct'. This indicates a variable that is handled 'by value'. The solution to your problem is to make your start and end in the Lerp() Vector3s. At the point you start the Lerp you would do:
var startPos = transform.position;
var endPos = endTransform.position;
Then your Lerp will be:
transform.position = Vector3.Lerp(startPos,endPos,timeClamped);
thanks! also for anyone interested, see my answer for working script.
Answer by cheliotK · Dec 16, 2013 at 04:09 PM
Hmm, problem is (weirdly) solved, after robertbu's comment. Here's the full working Update() function:
function Update () {
if(Input.GetKeyUp(KeyCode.Space) && !zoomStarted){
startTransform = GameObject.Find("start").transform;
// startTransform = transform; //this one was giving the problem
zoomStartTime = Time.time;
zoomStarted = true;
camZoom = true;
}
if(camZoom){
timeInZoom = Time.time-zoomStartTime;
timeClamped = timeInZoom/zoomDur;
transform.position = Vector3.Lerp(startTransform.position,endTransform.position,timeClamped);
transform.eulerAngles = Vector3.Lerp(startTransform.eulerAngles,endTransform.eulerAngles,timeClamped);
if(yPrev==transform.position.y){
Debug.Break();
}
}
yPrev = transform.position.y;
}
I created an empty GameObject and positioned it at the start location, and used that object's Transform as the startTransform. This seemed to solve the problem.
However, I still can't figure out why the commented line was giving me a problem. As I understand it, if I was using the "startTransform = transform;" line instead of "startTransform = GameObject.Find("start").transform;", what should happen is that the startTransform var should only be assigned the value ONCE, since it's inside an if statement with a key press. For some reason though, it must have kept assigning it the camera's new transform values each frame, hence making the lerp faster.
If someone would care to elaborate, I would be interested in knowing why the previous approach didn't work. (Also, thanks to robertbu for the suggestion that led to the solution!)
Don't need the empty game object. Just use Vector3s in the Lerp().
Your answer
Follow this Question
Related Questions
My Vector3.Lerp is not working. Please look at my script. 2 Answers
Lerp not working 1 Answer
Vector3.Lerp stick halfway 2 Answers
How to use Vector3.Lerp without slow-down 3 Answers
How the heck does Mathf.Lerp work? 2 Answers