Search code examples
unity-game-enginelerp

Unity-I can't seem to lerp my GameObject's Color


I'm just trying to make an observer pattern program one object randomly changes color and causes a group of other objects to change the same color, but I wanted them to gradually change over 5 seconds. I'm trying lerp, but it just instantly swaps colors. I think it maybe has something to do with the lerp's starting color, because the main object is constantly shifting colors and new colors become old colors. So I need to think of how choose a starting color for the lerp. I'm not sure if this has to do with my the lerp isn't working, but it's what I'm considering. If anyone else has any suggestions, I would appreciate it. Thank you.

public class Subject : MonoBehaviour {

public float timer = 0.0f;
public GameObject[] observers;
float t = 0;


Color oldColor;

void Update () {
    t += Time.deltaTime / 5.0f;
  timer += Time.deltaTime;

  if (timer >= 10f) {
    Color newColor = new Color(Random.value, Random.value, Random.value, 1.0f);
    GetComponent<Renderer>().material.color = newColor;

    for (int i = 0; i < observers.Length; i++) {
      observers[i].GetComponent<Renderer>().material.color = Color.Lerp(oldColor, newColor, t);
    }
    newColor=oldColor
    timer = 0;
    }
  }
}

Solution

  • What Color.Lerp(Color a, Color b, float t) does is

    Linearly interpolates between colors a and b by t

    For example, Color.Lerp(Color.blue, Color.red, 0.5f) returns a half way interpolation between blue and red. When you say Color.Lerp(oldColor, newColor, 5) it will return newColor, because

    t is clamped between 0 and 1. When t is 0 returns a. When t is 1 returns b.

    So 5 is the same thing as putting in 1.

    So you will need to keep a t variable somewhere that starts at 0 and increments up to 1, you put into Lerp.

    For example:

    float t = 0;
    private void Update()
    {
        t += Time.deltaTime / 5.0f; // Divided by 5 to make it 5 seconds.
    
        this.GetComponent<Renderer>().color = Color.Lerp(oldColor, newColor, t);
    }
    

    https://docs.unity3d.com/ScriptReference/Color.Lerp.html

    EDIT

    Also whats happening in your code, assuming you reset t when timer hit

    1. Timer >= 10.0f
    2. Lerp once
    3. Reset timer to 0

    . What you could do instead is something like this (i took out the observers and stuff just to make it easier to see)

    float t, timer;
    bool lerping = false;
    Color newColor;
    void Update()
    {
        t += Time.deltaTime / 5.0f;
        timer += Time.deltaTime;
    
        if (timer >= 10f)
        {
            lerping = true;
            t = 0;
            newColor = new Color(Random.value, Random.value, Random.value, 1.0f);
            Debug.Log("Lerping!");
            timer = 0;
        }
    
        if (lerping)
        {
            GetComponent<Renderer>().material.color = Color.Lerp(oldColor, newColor, t);
            if (t >= 1.0f)
            {
                lerping = false;
                Debug.Log("Stopped lerping");
            }
    
        }
    }