I have a simple script that changes the emission color based on a bool.

  • The first color is its idle color, which transitions between orange and light purple using a lerp weighted with a sine wave.

  • The second color is its "isinDanger" state, and this lerps between orange and red.

Is there any way to make the transition between both of these color variants smooth? When the bool is set to true the colors switch instantly with no transition. I've tried numerous things to try to get them to be smooth but ultimately it just breaks the lerping.

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

public class GemGlowOrange : MonoBehaviour
    public Material Mat;
    Color Red;       
    Color lightpurple;        
    Color orange;
    public bool isInDanger = false;
    Color CurrentColor;
    float startTime;
    public float speed = 1.0f;        
    void Start() {        
        startTime = Time.time; // time since game started
        orange =  new Color(1.320755f, 0.5346785f,0.2928088f,1f); // making my colours RGBA
        Red = new Color(0.858f, 0f,0f,1f);
        lightpurple = new Color(1.320755f,0.2973427f,0.8263685f,1f);
        var Mat = GetComponent<Renderer>().sharedMaterial;
        // making a reference to the material so we can enable the emission keyword if you do not want this to affect every object using this
        //material then use "Getcomponent<Renderer>().material" the same goes with setting the color as you can see further down.
        Mat.EnableKeyword("_EMISSION"); // this is making sure this shader has the emission keyword enabled.
    void Update() {
        float frac = (Mathf.Sin(Time.time - startTime) * speed);    
        CurrentColor = Mat.GetColor("_EmissiveColor");
        if (!isInDanger) {                   
            Mat.SetColor("_EmissiveColor", Color.Lerp(lightpurple, orange, frac));
            // getting the same material over and over again each frame and updating its
            // emission colour       
        } else if (isInDanger) {                
            Mat.SetColor("_EmissiveColor", Color.Lerp(Red, orange, frac)); // if it is in danger then it will alternate between red and orange.   

1 Answer 1


"I've tried numerous things"

Well, since you didn't tell us what "numerous things" you tried, we can't tell if you already tried just lerping your input colours, then lerping the result:

float dangerLevel;

void Update() {
    float transitionDuration = 0.5f;

    // Gradually transition between 0 (no danger) and 1 (danger)
    // over the specified transition duration in seconds.
    dangerLevel = Mathf.MoveTowards(
                     isInDanger ? 0f : 1f,

    // Sine wave.
    float frac = Mathf.Sin(Time.time - startTime) * speed;

    // Our colour at the low trough of the sine wave is determined by our danger level.
    var lowColor = Color.Lerp(lightpurple, red, dangerLevel);

    // Our colour at the high peak of the sine wave is always orange.
    // (Though you could lerp a highColor variable for this purpose too).
    Mat.SetColor("_EmissiveColor", Color.Lerp(lowColor, orange, frac));

But that should cover what you need.

  • \$\begingroup\$ im new to all this, only been doing it for just over a month, i appreciate the constructive criticism, and thankyou my friend i will give it a try! \$\endgroup\$
    – Billy
    Commented Jul 22, 2020 at 16:53
  • \$\begingroup\$ i had to apply something to my terrain to update my terrain materials as im using Nature renderer and once i did this, i applied the script to my prefab and then reapplied it as the tree instance in my paint trees and it works, thankyou my friend! \$\endgroup\$
    – Billy
    Commented Jul 22, 2020 at 18:37
  • \$\begingroup\$ @Billy remember to mark the answer as accepted if it answers you question \$\endgroup\$ Commented Aug 21, 2020 at 21:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .