- Home /
Mathf.Lerp float between 0 and 1 based on boolean input
I'm trying to lerp a float value from the current value to 1 if the boolean is true and from the current value to 0 if the boolean is false.
The function should result in a simulation of a getAxis(horizontal) keypress when the horizontal value gradually increases till 1 when the key is pressed and decreases down to 0 when released.
I tried this:
public float leftNumber;
public bool leftBool;
float lerpSpeed = 0.3f;
private void Update()
{
if (leftBool)
{
leftNumber = Mathf.Lerp(leftNumber, 1, lerpSpeed);
}
else
{
leftNumber = Mathf.Lerp(leftNumber, 0, lerpSpeed);
}
}
The result:
leftbool = true
leftNumber value increases very fast to 0.9999999.
leftbool = false
leftNumber value decreases very slowly to 1.401298e-45
I also tried:
void Update()
{
if (rightBool)
{
if (rightNumber < 1f) rightNumber += 0.01f;
}
else
{
if(rightNumber > 0f) rightNumber -= 0.01f;
}
}
The result:
rightbool = true
rightNumber value increases to 1.009999
rightbool = false
rightNumber value decreases to -0.009999925
What I want to achieve
leftbool = true
leftNumber value increases to 1
leftbool = false
leftNumber value decreases to 0
Both should be at the same "speed"
Answer by Hellium · Mar 14, 2020 at 11:16 PM
public float leftNumber;
public bool leftBool;
public float lerpSpeed = 0.3f;
private float timer;
private void Update()
{
if (leftBool)
timer = Mathf.Clamp01(timer + Time.deltaTime * lerpSpeed);
else
timer = Mathf.Clamp01(timer - Time.deltaTime * lerpSpeed);
// OR
// timer = Mathf.Clamp01(leftBool
// ? timer + Time.deltaTime * lerpSpeed
// : timer - Time.deltaTime * lerpSpeed);
leftNumber = Mathf.Lerp(0, 1, timer);
}
This sets the leftNumber value on: 0.00990173 at start and when I set leftBool = true , does nothing.
It works perfectly fine here. $$anonymous$$ind the parameters in the Lerp function.
I must have missed something. You are right, it works! Thanks.
Note that this line:
leftNumber = $$anonymous$$athf.Lerp(0, 1, timer);
could be replaced by this:
leftNumber = timer;
At least in this specific case. timer is already a value that is clamped between 0 and 1. So lerping between the values 0 and 1 by using a value that is between 0 and 1 is pretty pointless ^^.
ps: To mimic the old input manager behaviour you would use two seperate "lerpSpeed" values. Specifically "sensitivity" to increase the value and "gravity" to decrease the value.
Of course when you want to define a virtual axis that goes between -1 and 1 and rests at 0 I would recommed using $$anonymous$$athf.$$anonymous$$oveTowards ins$$anonymous$$d. Something like
if (!leftBool && !rightBool)
axis = $$anonymous$$athf.$$anonymous$$oveTowards(axis, 0f, gravity * Time.deltaTime);
if (leftBool)
axis = $$anonymous$$athf.$$anonymous$$oveTowards(axis, 1f, sensitivity * Time.deltaTime);
if (rightBool)
axis = $$anonymous$$athf.$$anonymous$$oveTowards(axis, -1f, sensitivity * Time.deltaTime);
Note I have 3 seperate if statements to allow cancellation of the acceleration. So the user could hold down both buttons and would stay at the current axis value since the increase and decrease would cancel each frame. "gravity" only kicks in when you release both buttons. The old input system has some additional features like snap to 0 when you press the other direction. So the axis doesn't need to slow down before speeding up in the other direction. Though this is getting to complex for a comment ^^.
Answer by KokodokoGames · Jul 26, 2020 at 12:55 PM
I was able to get back and forwards movement with tweened values using Math.MoveTowards, as @Bunny83 pointed out! You don't even need if
statements!
// input is 1 or 0 or -1
float inputValue = controls.Driving.Speed.ReadValue<float>();
// increase or decrease from current value to new input
currentValue = Mathf.MoveTowards(inputValue, currentValue, 0.25f * Time.deltaTime);
// apply to transform
transform.Translate(Vector3.forward * Time.deltaTime * currentValue * speed);
Answer by Link17x · Mar 15, 2020 at 12:11 AM
Lerp is not working how you think it is. The third parameter is the 'current' position between the start and end value. This obviously wants to be updated or it will never move, which is why we use Time.deltatime to update it between 0 and 1 (or whatever start/end value you have).
Instead, try something like
private float LerpTime = 1;
private float m_CurrentTime;
private void Update()
{
while (leftBool & m_CurrentTime < m_LerpTime)
{
m_CurrentTime += Time.deltaTime;
var percent = m_CurrentTime / m_LerpTime;
leftNumber = Mathf.Lerp(startNumber, endNumber, percent);
}
}
If leftBool is true, then it should lerp to the end value instead of getting stuck at 0.999999. There are a couple of issues with this though...
If you introduce your "else" here, then it will constantly try to lerp to 0 until leftBool becomes true. Which means you might want to introduce some condition to trigger the whole thing.
You will also need to reset the timer once the lerp has completed its cycle if you want it to be able to run more than once that is (presumably you do). But one thing to consider is if it is currently lerping towards 1, and leftBool becomes false, do you want it to cancel its lerp towards 1 and start lerping back to 0?
It might be worth checking out coroutines, where you can use it to lerp, but also cancel the current coroutine running if it gets called again. Then you ensure only one lerp is happening at once.
Your answer
Follow this Question
Related Questions
Mathf.Lerp supposed to be in Update()? 2 Answers
onFilterAudioRead Problems 0 Answers
what the hell is a int? (or a float, or boolean, or string!) 3 Answers
Integer gets too many additions 2 Answers
Converting Variables 3 Answers