Search code examples
user-interfaceunity-game-enginefade

How to fade in UI image in Unity


I want to fadein a UI image from transparent(alpha=0) to alpha=1, i thought my approach should be right, but it doesn't work, the image is not changing.

This is the code that i tried for doing that:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Fadein : MonoBehaviour {


    public float FadeRate;
    private Image image;
    private float targetAlpha;

    // Use this for initialization
    void Start()
    {
        image = GetComponent<Image>();
        Material instantiatedMaterial = Instantiate<Material>(image.material);
        image.material = instantiatedMaterial;
        targetAlpha = image.material.color.a;

        Invoke("startFadein", 1);

    }

    IEnumerator FadeIn()
    {
        targetAlpha = 1.0f;
        Color curColor = image.material.color;
        while (Mathf.Abs(curColor.a - targetAlpha) > 0.0001f)
        {
            curColor.a = Mathf.Lerp(curColor.a, targetAlpha, FadeRate * Time.deltaTime);
            image.material.color = curColor;
            yield return null;
        }
    }

    void startFadein()
    {

        StartCoroutine(FadeIn());
    }
}

The image is not changing. But i tried fadeout by using this code, from 1 to 0, it just worked, i have no idea why the fadein doesn't work?


Solution

  • image.material.color is not what you think it is

    With a few debug lines I was able to determine that the image material's alpha reports that it is 1 even when I set the image color multiplier to 0.

    If I override the curColor to have a 0 and let the loop do its thing, the image never appears either.

    This is because this:

    image color

    Is not image.material.color. It's image.color.

    Thus your fixed code would be:

    IEnumerator FadeIn() {
        targetAlpha = 1.0f;
        Color curColor = image.color;
        while(Mathf.Abs(curColor.a - targetAlpha) > 0.0001f) {
            Debug.Log(image.material.color.a);
            curColor.a = Mathf.Lerp(curColor.a, targetAlpha, FadeRate * Time.deltaTime);
            image.color = curColor;
            yield return null;
        }
    }
    

    Additionally a few other things:

    • Your code does not lerp the color linearly. I'm sure you knew that, and you're probably fine with that, but I figured I'd point it out.
    • You don't need Invoke("startFadein", 1);. You can just call StartCoroutine(FadeIn()); and put yield return new WaitForSeconds(1) at the top.
    • Your image will never actually reach the target value, it'll be close, but not equal. You can fix this by putting curColor.a = targetAlpha; image.color = curColor; after the while loop.