Color.lerp not working properly

I looked around to see if anyone had a similar issue but nothing like i had… when i run the script the color does change but it just goes to white and then gets whiter, also seems like the intensity increases but that might just be my eyes playing tricks on me

public Camera gameCamera;
	public Camera menuCamera;
	public Light mainLight;
	public Material pipe;
	public Material pipeWall;

	private float[,,] colorPalette = new float[4, 5, 3]
	{
		{ {166, 212, 159}, {156, 179, 128}, {82, 42, 39}, {199, 62, 29}, {197, 152, 73} },
		{ {20, 49, 9}, {170, 174, 127}, {208, 214, 179}, {247, 247, 247}, {239, 239, 239} },
		{ {202, 207, 214}, {214, 229, 227}, {159, 216, 203}, {81, 118, 100}, {45, 51, 25} },
		{ {255, 204, 51}, {102, 102, 102}, {255, 153, 0}, {255, 255, 255}, {166, 38, 57} }
	};


	private int palette;

	public float colorChangeReset = 10;
	private float colorTimer;

	private void Awake()
	{
		palette = Random.Range(0, colorPalette.GetLength(0) - 1);
		ChangeColor(palette);
		colorTimer = colorChangeReset;
	}

	private void Update()
	{
		colorTimer -= Time.deltaTime;
		if (colorTimer <= 0)
		{
			ChangeColor(palette);
			colorTimer = colorChangeReset;
		}

	}

	private void ChangeColor(int palette)
	{
		gameCamera.backgroundColor = menuCamera.backgroundColor = RenderSettings.fogColor =
			Color.Lerp(gameCamera.backgroundColor, new Color
			(colorPalette[palette, 0, 0], colorPalette[palette, 0, 1], colorPalette[palette, 0, 2]), Time.deltaTime * 2);
		
		mainLight.color = Color.Lerp(mainLight.color, new Color
			(colorPalette[palette, 1, 0], colorPalette[palette, 1, 1], colorPalette[palette, 1, 2]), Time.deltaTime * 2);
		
		pipe.color = Color.Lerp(pipe.color, new Color
			(colorPalette[palette, 2, 0], colorPalette[palette, 2, 1], colorPalette[palette, 2, 2]), Time.deltaTime * 2);

        RenderSettings.ambientLight = Color.Lerp(RenderSettings.ambientLight, new Color
			(colorPalette[palette, 3, 0], colorPalette[palette, 3, 1], colorPalette[palette, 3, 2]), Time.deltaTime * 2);

        pipeWall.color = Color.Lerp(pipeWall.color, new Color
			(colorPalette[palette, 4, 0], colorPalette[palette, 4, 1], colorPalette[palette, 4, 2]), Time.deltaTime * 2);

		palette++;
		if (palette >= colorPalette.GetLength(0) - 1)
		{
			palette = 0;
		}
	}

You have several problems with your code. First of all Random.Range with int parameters has the upper limit exclusive, so don’t subtract 1 from the Lenght. Random.Range(0, 3) will return a number between 0 and 2 inclusive (0,1 or 2).

The next problem which is your actual problem is that the Color struct uses float value in the range of 0f - 1f. You seem to want to use value in the range of 0 -255 (byte values). Unity has another struct called Color32 which does use bytes instead of floats. So you either have to divide your current values by “255f” or turn the float array into a byte array and use the Color32 struct instead.

Finally you should be aware that you use Lerp not as a linear interpolating function but as a smoothing function which is not entirely framerate independend and is not linear at all. The way you use it it has an asymptotic behaviour and will mathematically never reach it’s target, it just gets closer and closer.

Lerp always does the same and it does work as it should. Lerp simply does this:

Color Lerp(Color a, Color b, float t)
{
    return a + (b-a)*t;
}

edit
Finally using a multidimensional array like this is a bit cryptic. You might want to use a small custom class for that and directly use Color values.

[System.Serializable]
public class ColorSettings
{
    public Color gameBackground;
    public Color mainLight;
    public Color ambientLight;
    public Color pipe;
    public Color pipeWall;
}
public ColorSettings[] colorPalette;

This way you could set your color settings in the inspector and it’s easier to use and more clear what the code does.

If you really want to hardcode those settings in your code you can still do this:

public ColorSettings[] colorPalette = new ColorSettings[] {
    new ColorSettings {
        gameBackground = new Color32(166, 212, 159, 255),
        mainLight = new Color32(156, 179, 128, 255),
        pipe = new Color32(82, 42, 39, 255),
        ambientLight = new Color32(199, 62, 29, 255),
        pipeWall = new Color32(197, 152, 73, 255)
    },
    new ColorSettings {
        gameBackground = new Color32(20, 49, 9, 255),
        mainLight = new Color32(170, 174, 127, 255),
        pipe = new Color32(208, 214, 179, 255),
        ambientLight = new Color32(247, 247, 247, 255),
        pipeWall = new Color32(239, 239, 239, 255)
    },
    new ColorSettings {
        gameBackground = new Color32(202, 207, 214, 255),
        mainLight = new Color32(214, 229, 227, 255),
        pipe = new Color32(159, 216, 203, 255),
        ambientLight = new Color32(81, 118, 100, 255),
        pipeWall = new Color32(45, 51, 25, 255)
    },
    new ColorSettings {
        gameBackground = new Color32(255, 204, 51, 255),
        mainLight = new Color32(102, 102, 102, 255),
        pipe = new Color32(255, 153, 0, 255),
        ambientLight = new Color32(255, 255, 255, 255),
        pipeWall = new Color32(166, 38, 57, 255)
    },
};

As long as the “colorPalette” array is public it will still use the values you set in the inspector. If you only want to hardcode the values you might want to use the NonSerialized attribute or make the variable private.

Note: i quickly “copied & pasted” your values over. There might be some errors so check your values. I used the same order as you used so it should be correct.

*** second edit***

I just discovered that you call your “ChangeColor” method only once every 10 seconds. That won’t work with Lerp at all, no matter if you use it “correctly” or as a smoothing function. Since you only call ChangeColor once every 10 seconds you only update your colors once every 10 seconds. If that’s actually want you want, using Time.deltaTime is completely wrong here. DeltaTime is only used for things that are executed once a frame since deltaTime is the time difference between two frames. Using it in a method that isn’t called every frame makes no sense at all.

From your code it’s not clear what behaviour you’re after. If you want more information, you should tell us what exact behaviour you want to achieve.

Unity’s docs doesn’t explain Lerping well. Read this tutorial instead: Using Vector3.Lerp() correctly in Unity — One Man's Trash is Another Man's Blog

The guide is on Vector3.Lerp but it’s the same principle. The third variable is not the speed to move toward the 2nd color but a percentage between the two colors.