- Home /
[C#] can someone give me a detailed explanation of lerp
More specifically a vector2.lerp
, though I need to know how to make it work in general. I'm trying to use a lerp to send out multiple ray casts and it isn't working correctly.
I'll post the code involved with the lerp I am trying to use.
RaycastHit2D Raycaster(float rayLength, Vector2 dir, Vector2 origin, float velocity){
RaycastHit2D hitInfo;
float distance = box.height / 2 + (grounded? margin : Mathf.Abs(velocity * Time.deltaTime));
Vector2 direction = velocity > 0? -dir * 20 : dir * 20;
Debug.DrawRay(origin, direction, Color.red);
hitInfo = Physics2D.Raycast(origin, direction, rayLength * 20, 1 << LayerMask.NameToLayer("NormalCollisions"));
return hitInfo;
}
void Gravity(){
bool connected = false;
float lerpAmount = (float)boxCollider.size.x / (float) (verticleRays - 1);//rays -1 because otherwise we dont get to 1.0
Vector2 startPoint = new Vector2((-boxCollider.size.x / 2) + transform.position.x, (-boxCollider.size.y / 2) + transform.position.y);//these are used to position the raycasts on the horizontal axis
Vector2 endPoint = new Vector2((boxCollider.size.x / 2) + transform.position.x, (-boxCollider.size.y / 2) + transform.position.y);
Vector2 origin = Vector2.Lerp(startPoint, endPoint, lerpAmount * Time.deltaTime);
//an elegent way to apply gravity. subtract from y speed with terminal velocity = maxFall
velocity = new Vector2(velocity.x, Mathf.Max(velocity.y = gravity, -maxFall));
float newVelocityY = velocity.y;
float rayLength = box.height / 2 + Mathf.Abs (newVelocityY * Time.deltaTime);
for(int i = 0; i < verticleRays; i ++){
print ("BoxSize: " + boxCollider.size.x + " LerpAmount: " + lerpAmount + " lerpAmount * time: " + (lerpAmount * Time.time) +
" lerpamount * deltatime: " + (lerpAmount * Time.deltaTime) + " origin: " + origin + " startpoint: " + startPoint +
" endpoint: " + endPoint + " boxSize: " + boxCollider.size.x + " time.deltatime: " + Time.deltaTime +
" time.time: " + Time.time);
RaycastHit2D hitInfo = Raycaster(rayLength, Vector2.up, origin, newVelocityY);
connected = hitInfo;
print ("Ray fraction " + hitInfo.fraction);
if(!connected){
transform.Translate(-Vector2.up * (gravity * Time.deltaTime));
velocity = new Vector2(velocity.x, 0);
}
if(connected){
if(hitInfo.fraction > 0){
transform.Translate(-Vector2.up * (gravity * Time.deltaTime));
velocity = new Vector2(velocity.x, 0);
print ("Gravity activated");
break;
}
}
}
}
Now the trouble I'm having is that its not 'lerping' when I use time.deltatime
, it literally just sends all my raycasts from the start point. If I change the lerpamount
sometimes it will make one interpolation. It moves if I use time.time
but it moves in much smaller units than the lerpamount
and I dont wont to use time.time
for obvious reasons.
This is essentially the section of code (Its in the code above but I'm putting it here for clarity) that I've been working with to edit the variables in my vector2.lerp
.
float lerpAmount = (float)boxCollider.size.x / (float) (verticleRays - 1);//rays -1 because otherwise we dont get to 1.0
Vector2 startPoint = new Vector2((-boxCollider.size.x / 2) + transform.position.x, (-boxCollider.size.y / 2) + transform.position.y);//these are used to position the raycasts on the horizontal axis
Vector2 endPoint = new Vector2((boxCollider.size.x / 2) + transform.position.x, (-boxCollider.size.y / 2) + transform.position.y);
Vector2 origin = Vector2.Lerp(startPoint, endPoint, lerpAmount * Time.deltaTime);
The vector2 origin
heading is the main one that I am editing and its where 'I' think most of the issues are. I could however be wrong, and the problem could be anywhere. My next guess would be lerpAmount
or where I call Raycaster
inside the for loop.
I read the description of lerp in the unity docs, I've read a wikipedia page on it, I'm really pretty sure I understand what its supposed to be doing. I give it a start point and an end point, and an amount to move by then it cycles from one end to the other moving the lerpAmount
with each cycle.
I've read that its commonly used with time.deltaTime
but for some reason thats not working for me. I also would expect it to start fresh each time the function it exists in is called but for some reason (maybe I need to make it static?) thats not working either. With all that in mind if someone could fill me in on what I'm doing wrong using this lerp function that would be great.
Thanks in advance for any help that is given.
Answer by Benproductions1 · Apr 16, 2014 at 08:22 AM
"Lerp" stands for "Linear Interpolation" and can be defined mathematically as:
lerp(a, b, t) = a + (b - a)*t
You can think of it like this: a
is my initial value, b
is my target value and t
is how far along I am between the two values.
So if t
is 0
, i'm still at the start and if it's 1
I have reached my goal. If it's 0.5
I'm exactly halfway there, if it's 0.25
i'm a quater of the way there, etc.
As you have noted, it is commonly used to move from a initial to a target location. So far I have noted two quite popular ways of using lerp:
The first way is probably the most common and results in "smooth" movement towards the target, with the ongoing value never actually reaching the target:
//start
ongoing = initial
//update
ongoing = lerp(ongoing, target, time.deltatime*speed)
As you can see, each frame we aren't actually moving from the initial to the target location, but rather we are moving a little bit towards the target from our current location. As we get closer to our target, we move slower and vice-versa. speed
in this case has nothing to do with actual speed, it's simply an arbitrary multiplier.
The second method results in actual linear interpolation. This can come in many forms, but I like this one for pure simplicity
//start
start_time = -time.time()
//update
ongoing = lerp(initial, target, (start_time + time.time())/speed)
As you can see, this relies on time, ie. it will take speed
seconds to get there, and results in nice, linear interpolation. You can do more calculations with distance so that speed
is the actual amount of value per second, but that's beside the point.
What you have is a combination of these two:
ongoing = lerp(initial, target, time.deltatime*speed)
Meaning that every frame, ongoing
will move for one frame towards the target, from the initial. Every frame the ongoing
value is calculated from the initial. This can't work.
Thank you so much. I'm pretty sure I understand how it works, what I was doing wrong, and what I need to do. So yeah thanks a ton, now I can go fix my code.