# How can I change object material color using time and lerp?

I'm using the following code to change the color over time.

The coloring part is working but it's changing the color too fast. Even if I change the duration value to 5 or 10 it's changing the colors less then a second and it should be 5 seconds. I tried in the Inspector to change the duration to 10 but it didn't effect, still too fast.

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

public class ChangeScale : MonoBehaviour
{
public GameObject objectToScale;
public float duration = 1f;
public Vector3 minSize;
public Vector3 maxSize;

private bool scaleUp = false;
private Coroutine scaleCoroutine;

public Color startColor;
public Color endColor;
public float colorDuration = 5; // duration in seconds

private float t = 0; // lerp control variable

private void Start()
{
startColor = GetComponent<Renderer>().material.color;
endColor = Color.green;
objectToScale.transform.localScale = minSize;
}

// Use this for initialization
void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
//Flip the scale direction when F key is pressed
scaleUp = !scaleUp;

//Stop old coroutine
if (scaleCoroutine != null)
StopCoroutine(scaleCoroutine);

//Scale  up
if (scaleUp)
{
//Start new coroutine and scale up within 5 seconds and return the coroutine reference
scaleCoroutine = StartCoroutine(scaleOverTime(objectToScale, maxSize, duration));
}

//Scale Down
else
{
//Start new coroutine and scale up within 5 seconds and return the coroutine reference
scaleCoroutine = StartCoroutine(scaleOverTime(objectToScale, minSize, duration));
}
}

if (Input.GetKeyDown(KeyCode.C))
{
t = 0;
}
GetComponent<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;
}
}

IEnumerator scaleOverTime(GameObject targetObj, Vector3 toScale, float duration)
{
float counter = 0;

//Get the current scale of the object to be scaled
Vector3 startScaleSize = targetObj.transform.localScale;

while (counter < duration)
{
counter += Time.deltaTime;
targetObj.transform.localScale = Vector3.Lerp(startScaleSize, toScale, counter / duration);
yield return null;
}
}
}


When I press on C it's changing the colors but too fast.

What I want to do is when i press on C to change slowly and smooth the color of the object.

• Do you mean to use colorDuration instead of duration in the calculation of t? – Ed Marty Dec 25 '17 at 0:33
• @EdMarty right. – jdoedoe doedoe Dec 25 '17 at 0:54

You need to accumulate the time as it comes and use the accumulated time for the colorLerp method.

The idea is that the t parameter needs to be framed between a start and an end. The end is easy to get: it's the start plus the colorDuration. We set the start at 0 when our "trigger" occurs, in this case when you hit C.

Each frame brings an increment to our duration, which brings us further away from the start (which we refer to "time zero" or t = 0), and closer to our end, which is colorDuration. t is simply the ratio of that accumulated time over the maximum time we care about. This way, t will change from 0 to 1, which is what's expected by the colour lerping method.

private float timeAccumulatorForColor = 0; // Value used as the base for lerping the colour.

// [...]

if (Input.GetKeyDown(KeyCode.C))
{
t = 0;
timeAcc = 0;
}
if (t < 1)
{
// accumulate the time
timeAccumulatorForColor += Time.deltaTime;
// make sure it's between 0 and the colorDuration (which is our 'end' target)
timeAccumulatorForColor = Mathf.Clamp(0, colorDuration, timeAcc);
// convert it to a ratio properly usable for your colour lerping.
t = timeAccumulatorForColor / colorDuration;
}

• Note that I have not tested this code. – Vaillancourt Dec 25 '17 at 0:47