Muj
Muj

Reputation: 132

How to fade out / disapear a GameObject slowly?

I have a function where I have to dispear some GameObjects, at the moment I use SetActive(false) but it should not disapear instantly, it should disapear slowly in 2 or 3 seconds. I guess opacity should go slowly to transparent or something like that...

public void SlotCheck(string gemColor,GameObject slotColor,GameObject 
puzzleStuk,ref int scoreGem,ref bool Visibility)
{
if (DragHandler2.itemBegingDragged.name.Contains(gemColor)
DragHandler2.itemBegingDragged.transform.parent.name == "green_small_b")
     {
         Visibility=false;
         puzzleStuk.SetActive(Visibility);
         slotColor.SetActive(false);
         DragHandler2.itemBegingDragged.SetActive(false);
         scoreGem--;
     }

 }

Upvotes: 0

Views: 7581

Answers (4)

Hexodus
Hexodus

Reputation: 12945

This is my approach using coroutines.

void Awake()
{
    StartCoroutine(FadeOutMaterial(1f));
}

IEnumerator FadeOutMaterial(float fadeSpeed)
{
    Renderer rend = objectToFade.transform.GetComponent<Renderer>();
    Color matColor = rend.material.color;
    float alphaValue = rend.material.color.a;

    while (rend.material.color.a > 0f)
    {
        alphaValue -= Time.deltaTime / fadeSpeed;
        rend.material.color = new Color(matColor.r, matColor.g, matColor.b, alphaValue);
        yield return null;
    }
    rend.material.color = new Color(matColor.r, matColor.g, matColor.b, 0f);
}

Upvotes: 4

zambari
zambari

Reputation: 5035

As mentioned by previous answers, you can do it easily manipulating

meshrenderer.material.color=new Color (,,,x);

One important detail to add is that material needs to be set up in the transparent queue (and supports transparency). This is achieved via a dropdown in the material inspector, for Standard Surface shaders, but has to be dealt with in custom shaders by using one minus alpha blending mode and transparent queue in custom shaders

Tags {"Queue"="Transparent" "RenderType"="Transparent" }

Blend SrcAlpha OneMinusSrcAlpha

Upvotes: 0

derHugo
derHugo

Reputation: 90724

You can use a Coroutine combined with Color.Lerp to reduce the alpha value of all materials over time.

(I'm assuming you mean meshes with Renderers here not UI stuff but this would work in similar ways as well)

// How long should fading take (in seconds)
public float fadingDuration = 1;

// For storing Renderer components
private Renderer[] renderers;

// For storing original color data
private List<Color> originalColors = new List<Color>();

// For storing FadeOut color data
// (= Original data with alpha=0)
private List<Color> fadeOutColors = new List<Color>();

private void Awake() {
    // Get all renderers, own and children
    renderers  = GetComponentInChildren<Renderer>(true);

    // Run through renderers
    foreach(var rend in renderers)
    {
        // Run through all materials
        foreach (vat mat in rend.materials)
        {
            // Get original color
            var color = mat.color;
            // Add to original list
            originalColors.Add(color);

            // Get fadeout color (alpha 0)
            var fadeoutColor = new Color(color.r, color.g, color.b, 0);

            // Add to fadeout list
            fadeoutColors.Add(fadeOutColor);
    } 
}

// Call this to start fading
public void StartFadeout()
{
    StartCoroutine(FadeOut());
}

private IEnumerator FadeOut()
{
    var timePassed = 0;

    while(timePassed < fadingDuration)
    {
        // Get factor between 0 and 1 depending on passed time
        var lerpFactor = timePassed / fadingDuration;

        // Run through all renderers
        int colorIndex = 0;
        foreach(var rend in renderers)
        {
            // Run through all materials
            foreach (vat mat in rend.materials)
            {
                // Set color interpolated between original and FadeOut color depending on lerpFactor
                mat.color = Color.Lerp(originalColors[colorIndex], fadeOutColors[colorIndex], lerpFactor);

                // Count up index
                colorIndex++;
            }
        }

        // Add time passed since last frame
        timePassed += Time.deltaTime;

        // return to render the frame and continue from here in the next frame
        yield return null;
    }

    // In the end just to be sure apply the final target values (FadeOut colors)
    // Alternatively you could also deactivate/destroy the object here

    // Run through all materials
    int colorIndex = 0;
    foreach(var rend in renderers)
    {
        // Run through all materials
        foreach (vat mat in rend.materials)
        {
            // Set color to final FadeOut value
            mat.color = fadeOutColors[colorIndex];

            // Count up index
            colorIndex++;
        }
    } 
}

Note that for transparency to work at all your materials have to use a shader supporting transparency.


This might however not be the best solution regarding performance. Especially since multiple Renderers might reference the same Material so in the current example there are maybe some redundancies.

But if you anyway have only one Renderer with one Material you could adjust the code a bit and skip all the loops ;)

Upvotes: 0

Charlie Malmqvist
Charlie Malmqvist

Reputation: 156

You can get the Renderer component of a GameObject and then change the alpha of the color gradually in Update().

Ex:

Renderer renderer;

void Start() {
    renderer  = GetComponent<Renderer>();
}

void Update() {
    Color oldCol = renderer.material.color;
    Color newCol = new Color(oldCol.r, oldCol.g, oldCol.b, oldCol.a - 0.01f);
    renderer.material.color = newCol;
}

Of course you shouldn't use hard coded values like 0.01f, but instead a value from the inspector. This should also be multiplied by Time.deltaTime as to not make the fade speed FPS-based.

Some of the names or the like might not be 100% correct in this example, but it should give you an idea of which part of the Unity API documentation to look around in.

Upvotes: 1

Related Questions