(Newbie) Need help changing an object's color over time

I am brand new to coding and Unity and I am working my way through the self paced training offered. This is the first time I’ve tried using a coroutine/Enumerator or the Color.Lerp function.

The goal is to create a cube that changes size, color, location, and rotation every 5 seconds or manually with Space. I thought I would be ambitious and try to make the color not only change with every new cube, but also shift to a new color before it randomizes again. Everything but the color shift seems be working fine.

Any help would be greatly appreciated. Please forgive the potentially sloppy script, I’ve only been at this a few weeks in my spare time.

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

public class Cube : MonoBehaviour
{
    public MeshRenderer Renderer;
    //Initial rotation speeds of cube, script doesn't seem to work without values listed
    private float rotateSpeedx = 10f;
    private float rotateSpeedy = 10f;
    private float rotateSpeedz = 10f;
    //Cube randomizer timer
    private float changeInterval = 5f;
    //Used for color shift
    private Color startColor;
    private Color endColor;
    void Start()
    {
        Invoke("change", 0f);
    
    }
   
    void Update()
    {
        //Rotates cube based off random number generated at start
        transform.Rotate(rotateSpeedx * Time.deltaTime, rotateSpeedy * Time.deltaTime, rotateSpeedz *Time.deltaTime);
       
        //Manually destroys cube and spawns a new cube with Spawner script
        if(Input.GetKeyDown(KeyCode.Space))
        {
            Destroy(gameObject);
        }

    }

    void change()
    {
        //Sets beginning color a and b for Lerp function
        startColor = Random.ColorHSV(0f, 1f, 0.5f, 1f, 0.75f, 1f, 0.5f, 1f);
        endColor = Random.ColorHSV(0f, 1f, 0.5f, 1f, 0.75f, 1f, 0.5f, 1f);

        //Randomizes cubes rotation speed
        rotateSpeedx = Random.Range(-100f, 300f);
        rotateSpeedy = Random.Range(-100f, 100f);
        rotateSpeedz = Random.Range(-100f, 200f);

        //Randomizes cubes start location
        transform.position = new Vector3(Random.Range(-10, 10), Random.Range(0, 5), Random.Range(-5, 5));
       
        //Randomizes cube size
        transform.localScale = Vector3.one * Random.Range(1f, 4f);
        //Runs color shifter
        StartCoroutine("ColorShift");
        //Repeats everything
        Invoke("change", changeInterval);
    }



   IEnumerator ColorShift ()
    {
        float timeStart = 0.0f;
        Material material = Renderer.material;
       
        //Shifts cube color
        while (timeStart < changeInterval)
        {
            Debug.Log(timeStart / changeInterval);
            material.color = Color.Lerp(startColor, endColor, timeStart / changeInterval);

            timeStart += Time.deltaTime;
        }
       
            material.color = endColor;
        //Not really sure why I need this other than to remove an errorcode
        yield return null;

    }
}

You actually want that yield return null; inside the while loop.

All code executes instantaneously and Unity locks up solid while your code runs, so your entire while loop happens in one frame.

HOWEVER, because you also want to interact with this color change, generally this isn’t a great application for coroutines.

I prefer this common mechanism for transitioning between two quantities, colors or whatever:

Smoothing movement between discrete values:

The code: Smooth movement - Pastebin.com

You would use the above and have two ways of changing color:

  • a timer that counts down and drives a new color
  • something watching for the keypress.

Either one sets the new desired color… the common code above tweens it to the new color.

Oh man, that alone solved it, but thank you for the tip and code on using a smoothing movement. I will play around with that as well and see if I can get it working with that method too.

1 Like