- Home /
Duplicate Question
Mathf.Lerp won't stop snapping
As is, this code will cause it to snap to the angle instead of lerp towards it. Smooth is set to 5 currently in the demo and it seems that the higher I put that number, the more angle I will get. Please play the demo to fully see the issue. Demo
I have tried Mathf.Lerp. Also, without the smooth value it will only ever so slightly budge. As if it's only doing it on one frame but I have checked and it's constantly being accessed.
if (ship.position.x > 5) {
angle = Mathf.LerpAngle(camera.rotation.y, 40f, Time.deltaTime * smooth);
camera.eulerAngles = new Vector3(10, angle, 0);
}
else if (ship.position.x < 2) {
angle = Mathf.LerpAngle(camera.rotation.y, -40f, Time.deltaTime * smooth);
camera.eulerAngles = new Vector3(10, angle, 0);
}
else {
angle = Mathf.LerpAngle(camera.rotation.y, 0f, Time.deltaTime * smooth);
camera.eulerAngles = new Vector3(10, angle, 0);
}
Figured it out.. just needed to change camera.rotation.y to camera.eulerAngle.y. Was just something I overlooked.
I converted your 'Answer' into a comment. Answers are reserved to attempts to answer a question. As for using eulerAngles, you may have issues because the representation is not fixed.
Answer by robertbu · May 10, 2013 at 04:33 AM
'rotation' is not what you thing it is. Please read my comments and suggestions about Quaternions and eulerAngles in my answer to this question:
http://answers.unity3d.com/questions/415717/rotate-an-element-with-exactly-value.html
Even if you change the code to use eulerAngles instead of rotation, you cannot depend on any specific eulerAngle representation. You could assign (180,0,0) to eulerAngles and immediately read it back and get (0,180,180) (the same physical rotation).
Answer by gharbill · May 10, 2013 at 05:01 AM
This is a common mistake in using Lerp. Lerp functions actually do not smooth the value towards the target automatically. they work like a slider, you have to manually change the slider value yourself and you can do it in your code. the slider is the t value which is a float and should be between 0 and 1. here is how Lerp functions:
LerpAngle (a : float, b : float, t : float)
it looks at t vlaue and gives you a number between "a" and "b". if "t" is 0 or less it returns "a", and if "t" is 1 or more, it returns "b" and if "t" is between 0 and 1 it gives you a number between "a" and "b" and uses "t" as the ratio.
what you did in your code is using Time.deltaTime * smooth
as t value which if used in update function, it is pretty much a constant. so Lerp will always return same number.
if you want your angle to change you have to give "t" parameter a value which increases/decreases every frame, so you have to use Time.time
instead and have a temporary variable as "now". here is a simple implementation:
private var now: float;
private var letMove: boolean = flase;
function myMove(){ // call myMove on this gameObject
// and it will start movement to x=10
now = Time.time;
letMove = true;
}
function Update(){
if (letMove){
transform.position.x = Mathf.Lerp(0,10,(Time.Time - now));
}
}
His use of Lerp() is found in many UA answers. It's kinda a "misuse" of the Lerp() in that it does not (as you point out) increment 't' from 0 to 1, and it produces an eased motion rather than a linear one. Typically you see in a line like:
transform.position = Vector3.Lerp(transform.position, target.position, speed * Time.deltaTime);
I was actually going for an eased look, and I achieved that so I will definitely read over these answers and try to understand what you're talking about, but I have gotten the functionality I am looking for now.
Got it. yes you are right. So which one do you recommend?
@gharbill - It depends on what you need. The big drawback of this "misuse" is that it does not cover the distance in any specified time nor at any specified speed. So you are stuck eyeballing the behavior to what feels right. Using a timer allows the Lerp() to cover the distance in a specified amount of time. And you can still ease the motion (and arrive on time) if you put the timer through an easing function. And then there is the lesser known cousin $$anonymous$$oveTowards() which allows the object to move at a specified speed.
I think the "misuse" gets used so much on UA because a) it is easy to write, and 2) it often feels better...more natural.
Follow this Question
Related Questions
Lerping & OnCollisionEnter - how do i lerp without update?? 1 Answer
Rotation jumping to a different rotation after rotating a certain amount 0 Answers
how to use time on lerp 2 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers