Home > Mobile >  Lerp never completes for color
Lerp never completes for color

Time:12-08

I am lerping between two colors continously, the second color is black, it never becomes black in the speed of 0.25 given. It gets to grey and then returns to original color. Why does this happen?

Also, how do I lerp between these two colors ONLY 3 times?

public MeshRenderer mr;

 private void Update () {
        mr.material.color = Color32.Lerp (new Color32 (221, 216, 216, 255), new Color32 (0, 0, 0, 255), Mathf.PingPong (Time.time, 0.25f));
}

CodePudding user response:

The second parameter of Mathf.PingPong is not a "speed" but rather called length and actually means the maximum reached value!

PingPong returns a value that will increment and decrement between the value 0 and length.

For the Lerp to reach (more or less) the second parameter you want to make sure to reach 1.

Your 0.25f seems to be trying to achieve a certain duration instead -> In order to do so you can apply a multiplier to the first time parameter like e.g.

[SerializeField] private Color32 start = new Color32 (221, 216, 216, 255);
[SerializeField] private Color32 end = new Color32 (0, 0, 0, 255);
[SerializeField] private float speed = 4f;

private void Update () 
{
    mr.material.color = Color32.Lerp (start, end, Mathf.PingPong (Time.time * speed, 1));
}

Makes PingPong go forth and back 4 times faster.

However, to control it better: PingPong by default takes 2 seconds to complete one iteration. So in order to make it rather take the given duration you want to

  • Multiply the time by 2 -> it runs 2 times faster -> The iteration takes half as long (1 second by default)
  • Divide the time by the given target duration

So you might want to rather provide an iteration duration instead of a speed modifier and do e.g.

[SerializeField] private Color32 start = new Color32 (221, 216, 216, 255);
[SerializeField] private Color32 end = new Color32 (0, 0, 0, 255);
[SerializeField] private float duration = 0.25f;

private void Update () 
{
    mr.material.color = Color32.Lerp (start, end, Mathf.PingPong (Time.time * (2f / duration), 1));
}

For the other question

Also, how do I lerp between these two colors ONLY 3 times?

I would actually recommend to not use PingPong at all.

Rather use a Coroutine like e.g.

[SerializeField] private Color32 start = new Color32 (221, 216, 216, 255);
[SerializeField] private Color32 end = new Color32 (0, 0, 0, 255);
[SerializeField] private float iterationDuration= 0.25f;
[SerializeField] [Min(1)] private int iterationAmount = 3;

private IEnumerator Start()
{
    for(var i = 0; i < iterationAmount; i  )
    {
        // fade to end
        for(var factor = 0f; factor < 1; factor  = Time.deltaTime / iterationDuration / 2f) 
        {
            mr.material.color = Color32.Lerp (start, end, factor);
            yield return null;
        } 

        // fade back to start
        for(var factor = 1f; factor > 0; factor -= Time.deltaTime / iterationDuration / 2f) 
        {
            mr.material.color = Color32.Lerp (start, end, factor);
            yield return null;
        } 
    }

    // to be sure to end clean
    mr.material.color = start;
}
  • Related