# Controlling duration of Color.Lerp in seconds

Hi everyone,

I’;ve asked a question similar to this recently, but it just got me wondering… How can you control the duration of Color.Lerp in seconds?

Take this code for example:

``````var startColor : Color;
var endColor : Color;

function Update() {
renderer.material.color = Color.Lerp(startColor, endColor, Time.time);
}
``````

How could modify this so I can explicitely control the duration of the transition in SECONDS?

The Lerp examples in the docs are terribly bad: using Time.time as the control variable limits things to the first second your game is playing! Ok, you could simply use Time.time/duration instead of just Time.time (duration in seconds), but this would not allow a new sequence without restarting the game.

That’s a simple example that allows duration control and sequence restarting:

``````var startColor : Color;
var endColor : Color;
var duration: float = 5; // duration in seconds

private var t: float = 0; // lerp control variable

function Update() {
renderer.material.color = Color.Lerp(startColor, endColor, t);
if (t < 1){ // while t below the end limit...
// increment it at the desired rate every update:
t += Time.deltaTime/duration;
}
}
``````

You can restart the Lerp sequence at any time just assigning 0 to t. A more elaborated version could do it when you press space, for instance:

``````var startColor : Color;
var endColor : Color;
var duration: float = 5; // duration in seconds

private var t: float = 0; // lerp control variable

function Update() {
if (Input.GetKeyDown("space")){
t = 0;
}
renderer.material.color = Color.Lerp(startColor, endColor, t);
if (t < 1){ // while t below the end limit...
// increment it at the desired rate every update:
t += Time.deltaTime/duration;
}
}
``````

Hi there.

I’ve not personally used the Color.lerp but I presume it works the same as any lerping function since the 3rd parameter is in the range 0 - 1.

I would recommend using Coroutines for this type of thing. Here is an example:

``````float duration = 5; // This will be your time in seconds.
float smoothness = 0.02f; // This will determine the smoothness of the lerp. Smaller values are smoother. Really it's the time between updates.
Color currentColor = Color.white; // This is the state of the color in the current interpolation.

void Start()
{
StartCoroutine("LerpColor");
}

IEnumerator LerpColor()
{
float progress = 0; //This float will serve as the 3rd parameter of the lerp function.
float increment = smoothness/duration; //The amount of change to apply.

while(progress < 1)
{
currentColor = Color.Lerp(Color.red, Color.blue, progress);
progress += increment;
yield return new WaitForSeconds(smoothness);
}
}
``````

I haven’t tested the code but I think it’s good enough to demonstrate.
If you don’t know coroutines I would strongly recommend learning about them. It’s very useful for animating things between 2 points. Not just colors but anything. It sure as hell beats keeping track of time variables in update loops.

#Slowly cycle the background color…

It’s remarkably easy to cycle through all the colors of the rainbow:

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

public class ColorCycle : MonoBehaviour {

// put this script on your camera
// it's great for a Canvas for your UI

private Camera cam;
private float cycleSeconds = 100f; // set to say 0.5f to test

void Awake() {

cam = GetComponent<Camera>();
}

void Update() {

cam.backgroundColor = Color.HSVToRGB(
Mathf.Repeat(Time.time / cycleSeconds, 1f),
0.3f,     // set to a pleasing value. 0f to 1f
0.7f      // set to a pleasing value. 0f to 1f
);
}
}
``````

That’s it.

For an object … with proper offset from the editor starting color look, etc.

``````using UnityEngine;
public class ObjectColorCycle : MonoBehaviour
{
public Renderer colorMe;

void Update()
{
Colorz();
}

float origHue = 0.5f;
float origSat = 0.5f;
float origVal = 0.5f;

void Start()
{
Color c = colorMe.material.color;
Color.RGBToHSV(c, out origHue, out origSat, out origVal);
}

private float cycleSeconds = 100f; // as you wish

void Colorz()
{
float h = Mathf.Repeat(origHue + Time.timeSinceLevelLoad / cycleSeconds, 1f);
colorMe.material.color = Color.HSVToRGB(h, origSat, origVal);
}
}
``````

That’s easy fortunately.