Random Color Changing with Lerp not working

I’ve been trying to change the camera background constantly with random colors, transitioning smoothly between them. My idea is: at the start of the game 3 colors are created, and there are 3 cycles. It starts with cycle 1, where it does a Lerp between newColor1 and newColor2, in cycle 2 between color 2 and 3, and in the end in cycle 3 between color 3 and 1, and (not yet implemented) creating each time new colors through cycles, so, in cycle 1 it creates a newColor3, in cycle 2 a newColor1 and in cycle 3 a new color 2. So the problem is, the colors keep changing as planned, but, they do without doing the Lerp, so they don’t change smoothly.

Here’s the code(don’t mind ColorChange() )
I tried both doing all in the update method and by creating 3 separate functions (ColorLerp1, 2, 3)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColorChanging : MonoBehaviour
{
    private float gameTime;
    private float cycleTime = 3f;

    public Camera cam;

    private Color newColor1;
    private Color newColor2;
    private Color newColor3;
    public float t = 3.0f;

    private void Start()
    {

        newColor1 = new Color
           (
            Random.value,
            Random.value,
            Random.value
            );

        cam.backgroundColor = newColor1;
        PlayerPrefs.SetInt("ColorCycle", 1);

        newColor2 = new Color
           (
           Random.value,
           Random.value,
           Random.value
           );
        newColor3 = new Color
           (
           Random.value,
           Random.value,
           Random.value
           );
    }

    private void ChangeColor()
    {
        newColor1 = new Color
                (
                  Random.value,
                  Random.value,
                  Random.value
                );
    }

    private void ColorLerp1()
    {
        cycleTime = gameTime + 3f;
        cam.backgroundColor = Color.Lerp(newColor1, newColor2, t);
    }

    private void ColorLerp2()
    {
        cycleTime = gameTime + 3f;
        cam.backgroundColor = Color.Lerp(newColor2, newColor3, t);
    }

    private void ColorLerp3()
    {
        cycleTime = gameTime + 3f;
        cam.backgroundColor = Color.Lerp(newColor3, newColor1, t);
    }

    private void Update()
    {
        gameTime = Time.timeSinceLevelLoad;

        if (gameTime > cycleTime && PlayerPrefs.GetInt("ColorCycle") == 1)
        {
            ColorLerp1();

            PlayerPrefs.SetInt("ColorCycle", 2);
        }

        if (gameTime > cycleTime && PlayerPrefs.GetInt("ColorCycle") == 2)
        {
            ColorLerp2();

            PlayerPrefs.SetInt("ColorCycle", 3);
        }

        if (gameTime > cycleTime && PlayerPrefs.GetInt("ColorCycle") == 3)
        {
            ColorLerp3();

            PlayerPrefs.SetInt("ColorCycle", 1);
        }

    }
}

That’s a lot of code… I’m not even really sure what’s happening there.

This is my go-to smooth-transition pattern, works for pretty much any continuous quantity:

Smoothing movement between any two particular values:

https://discussions.unity.com/t/812925/5

You have currentQuantity and desiredQuantity.

  • only set desiredQuantity
  • the code always moves currentQuantity towards desiredQuantity
  • read currentQuantity for the smoothed value

Works for floats, Vectors, Colors, Quaternions, anything continuous or lerp-able.

The code: https://gist.github.com/kurtdekker/fb3c33ec6911a1d9bfcb23e9f62adac4

I would also advise staying away from splattering crap like the above all over your code. Keep it tidy in one place to avoid typos and visual noise when reading the code.

Here’s an example of simple persistent loading/saving values using PlayerPrefs:

https://gist.github.com/kurtdekker/01da815d2dfd336a925ae38019c3a163

Useful for a relatively small number of simple values.

Unluckly I couldn’t find use in your code, but, on the other hand I managed to get a solution anyways, I’m gonna post it for whoever was interested in the topic:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColorChangingV2 : MonoBehaviour
{
    public Color color1;
    public Color color2;
    private float duration = 6f;

    private float gameTime;
    private float cycleTime;

    public Camera cam;

    void Start()
    {
        cam = GetComponent<Camera>();
        cam.clearFlags = CameraClearFlags.SolidColor;

        color1 = new Color
           (
           Random.Range(100,220),
           Random.value,
           Random.value
           );

        color2 = new Color
           (
           Random.Range(100, 220),
           Random.value,
           Random.value
           );

        cycleTime = 6f;

        PlayerPrefs.SetInt("ColorCycle", 1);
    }

    void RandomColor1()
    {
        color1 = new Color
           (
           Random.Range(100, 220),
           Random.value,
           Random.value
           );

        PlayerPrefs.SetInt("ColorCycle", 2);
    }

    void RandomColor2()
    {
        color2 = new Color
           (
           Random.Range(100, 220),
           Random.value,
           Random.value
           );

        PlayerPrefs.SetInt("ColorCycle", 1);
    }

    void Update()
    {
        gameTime = Time.timeSinceLevelLoad;

        float t = Mathf.PingPong(Time.time, duration) / duration;
        cam.backgroundColor = Color.Lerp(color1, color2, t);

        if (gameTime > cycleTime && PlayerPrefs.GetInt("ColorCycle") == 1)
        {
            cycleTime = gameTime + 6f;
            RandomColor1();
        }

        if (gameTime > cycleTime && PlayerPrefs.GetInt("ColorCycle") == 2)
        {
            cycleTime = gameTime + 6f;
            RandomColor2();
        }
    }
}

Note: the Random.Range could be a Random.value aswell, it’s just that I had a personal preference in how bright was the color.

P.S. thanks anyways for the help provided

You’re using the Color class wrong and you are not getting random colors the way you think you are. The Color constructor takes numbers between 0 and 1, NOT 0 to 255 as you are using it. Each and every one of your colors there is going to have 100% in the red channel.

I have no idea why you’re using PlayerPrefs in here. Just set an int variable.

Yeah that may seem confusing but it’s because I want the player to work with it later

Oh yeah, that makes absolute sense, it was very dumb by me to not think about it. Thanks for the tip!!