Search code examples
c#unity-game-enginerenderergameobject

Unity freezes when attempting to modify RGB colors


I am trying to modify the Color32 RGB values of a Unity Renderer component gradually over time, but whenever I play the game in Unity, it just freezes the program and I have to close out. I am certain that it is because of how I am trying to modify it, but I do not know where I am wrong. Any help would be greatly appreciated. Thank you.

void degradeGradually(Renderer ren){
    float time = Time.time; 
    Color32 col;
    while(((Color32)ren.material.color).r > 89f){
        if (Time.time - time > .025f) {
            time = Time.time;
            col = new Color32 ((byte)(((Color32)ren.material.color).r - 1f), (byte)(((Color32)ren.material.color).g - 1f), (byte)(((Color32)ren.material.color).b - 1f), 255);
            ren.material.color = col; 
        }
    }
}

Solution

  • It's because the while loop in this method never terminates and thus the Update that calls it never completes. This freezes your game.

    One possible solution is turning this method into a Coroutine (the documentation's first example is remarkably similar to your code!) and putting a return yield null at the end of your while loop:

    IEnumerator degradeGradually(Renderer ren){
        float time = Time.time; 
        Color32 col;
        while(((Color32)ren.material.color).r > 89f){
            if (Time.time - time > .025f) {
                time = Time.time;
                col = new Color32 ((byte)(((Color32)ren.material.color).r - 1f), (byte)(((Color32)ren.material.color).g - 1f), (byte)(((Color32)ren.material.color).b - 1f), 255);
                ren.material.color = col; 
            }
    
            yield return null;
        }
    }
    

    And then where you call it,

     // Instead of degradeGradually(r);
     StartCoroutine(degradeGradually(r));
    

    And if you need to do something directly after the degrading happens, you can add it to the bottom of degradeGradually.

                ...
                ren.material.color = col; 
            }
    
            yield return null;
        }
    
        DoStuffAfterDegrade();
    }
    

    Also, color component values range from 0f to 1f so you'll want to decrease them by something smaller than 1f each time. As written, you'll fade to black on the first frame you get inside the if statement. You also might have to clamp your components between 0f-1f if Unity gives you any trouble about putting in negative numbers.