Help with the loop.

If I’m running this the _shouldchange bool will change like 5-10 seconds too late to false even if the Lerp is completed? how can I fix that?

public class ColorCycler : MonoBehaviour
{

public Color[] Colors;

public float Speed = 5;
int _currentIndex = 0;
Camera _cam;
public bool _shouldChange = false;

public float time;
public float CycleEverySeconds = 5f;


void Start()
{
    _cam = GetComponent<Camera>();

    _currentIndex = 0;
    
}


public void SetColor(Color color)
{
    _cam.backgroundColor = color;
}

public void Cycle()
{
    _shouldChange = true;
}



void Update()
{
    
    time += Time.deltaTime;

    if (time >= CycleEverySeconds)
    {
        Cycle();
        time = 0;
    }
    if (_shouldChange == true)
    {

        var startColor = _cam.backgroundColor;

        var endColor = Colors[0];
        if (_currentIndex + 1 < Colors.Length)
        {
            endColor = Colors[_currentIndex + 1];
        }

        var newColor = Color.Lerp(startColor, endColor, Time.deltaTime * Speed);
        SetColor(newColor);

        if (newColor == endColor)
        {
            _shouldChange = false;
            if (_currentIndex + 1 < Colors.Length)
            {
                _currentIndex++;
            }
            else
            {
                _currentIndex = 0;
            }
        }
    }
}
}

You’re using lerp for a non-linear interpolation, which is not a bad thing to do, but you have to be aware what you’re doing.

When you do

value = lerp(value, target, speed * deltaTime)

what you do is go x% of the way from “here” to “there” each update. So when speed * deltaTime is, let’s assume that for now, 0.5, then you go 50% of the remaining way each time. If you have, say, 10 meters to go, you go 5 meters in the first update, 2.5 meters in the second, 1.25 meters, …

This creates this neat “start fast, get slower” kind of interpolation, but it also means that, in a mathematical sense, you never reach your target, as you always ever decrease your distance by half.

In a more programming sense, you can actually reach the target as at some point, the difference between the value and its target becomes too small for the computer to represent with the amount of bits available for representing the numbers.

So, what you need to do: You either rework the way your tween works or you introduce an “epsilon” value - a small value that is considered a threshold for being finished. If the remaining distance between value and target is below that threshold, you consider the interpolation done.

Instead of

if (newColor == endColor)

you would write something like (but probably not exactly like)

if (((Vector4)newColor - (Vector4)endColor).magnitude < 0.05f)

Keep in mind that this kind of interpolation is anything but consistent when done in Update. Even with Time.deltaTime applied in all the right places, you will get different durations for your animation with different FPS.