Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Making GUI Text fade away using coroutine?

Discussion in 'Scripting' started by tarzanno, Jun 4, 2015.

  1. tarzanno

    tarzanno

    Joined:
    Apr 23, 2015
    Posts:
    58
    Hi
    I made this script, which makes a random line from .txt file appear every 10 seconds. I'd like it to slowly disappear right after it appears on a screen in 2 seconds. I'm looking for a solution how to make a Text component alpha gradually change.

    This is the script:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.IO;
    4. using UnityEngine.UI;
    5. using System.Collections.Generic;
    6.  
    7. public class TextReadFromFile : MonoBehaviour {
    8.  
    9.     GameObject player;
    10.     public TextAsset wordFile;                                // Text file (assigned from Editor)
    11.     private List<string> lineList = new List<string>();        // List to hold all the lines read from the text file
    12.     Text text;
    13.     Timer timer;
    14.     PlayerHealth playerHealth;
    15.     public float delay;
    16.  
    17.     void Awake ()
    18.     {
    19.         player = GameObject.FindGameObjectWithTag ("Player");
    20.         playerHealth = player.GetComponent <PlayerHealth>();
    21.         text = GetComponent <Text>();
    22.     }
    23.     void Start()
    24.     {
    25.         ReadWordList();
    26.         Debug.Log("Random line from list: " + GetRandomLine());
    27.             //coroutine that shows text.
    28.         StartCoroutine (Count(delay));
    29.  
    30.         }
    31.  
    32.  
    33.  (...)
    34.  
    35.     //coroutine that waits 10 seconds before showing text (change seconds on the Start() ).
    36.     IEnumerator Count(float WaitTime){
    37.        
    38.         while(playerHealth.currentHealth >= 0)
    39.         {
    40.             yield return new WaitForSeconds(WaitTime);
    41.             text.text = GetRandomLine();
    42.  
    43.         }
    44. }
    45.  
    46.  
    47.  
    48. }
    The most important is that coroutine. I tried to make a coroutine inside a coroutine, but it wasn't running as planned. I don't know if this is even possible to change alpha of a text and I don't know if I should use coroutine or a for loop for that. I guess changing alpha to 0 should be enough as the text would be replaced by another text after for example 10 seconds (It will be deleted from memory and I don't have to Destroy(this)?).

    I'm thinking about using this example:
    Code (CSharp):
    1. IEnumerator Fade() {
    2.     for (float f = 1f; f >= 0; f -= 0.1f) {
    3.         Color c = renderer.material.color;
    4.         c.a = f;
    5.         renderer.material.color = c;
    6.         yield return new WaitForSeconds(.1f);
    7.     }
    8. }
    and just put

    Code (CSharp):
    1. StartCoroutine (Count(2F));
    inside

    Code (CSharp):
    1. IEnumerator Count(float WaitTime){
    2. (...)
    3. }
     
  2. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Here's an extension method that'll change the alpha of text.

    Code (csharp):
    1. public static void SetAlpha(this Text text, float alpha)
    2. {
    3.   Color c = text.color;
    4.   c.a = alpha;
    5.   text.color = c;
    6. }
    I use a combination of LeanTween and a helper method to do my text fading - note I've got some extra code to handle outlines on the text (in case you're using those, shown below):

    Code (csharp):
    1. LeanTween.value(gameObject, 0, 1, fadeDuration).setOnUpdate(delegate(float v)
    2. {
    3.     textObject.SetAlpha(v); // uses the extension method shown above.
    4. });
    If you've got any Outline scripts on your text, it will not fade them correctly unless you change the extension method to something like:

    Code (csharp):
    1. public static void SetAlpha(this Text text, float alpha)
    2. {
    3.     Color c = text.color;
    4.     c.a = alpha;
    5.     text.color = c;
    6.     float outLineAlpha = alpha*alpha*alpha;
    7.     Outline[] outlines = text.gameObject.GetComponents<Outline>();
    8.     for (int i = 0; i < outlines.Length; ++i)
    9.     {
    10.         Color oc = outlines[i].effectColor;
    11.         oc.a = outlineAlpha;
    12.         outlines[i].effectColor = oc;
    13.     }
    14. }
    Not the most efficient doing the GetComponents<> call each iteration, but for most uses this has been fine for me.

    EDIT: If you don't want to bother with extension methods (these just provide convenience way of 'extending' a method on a class. You can just redefine them as normal methods in the class you're using. I use extension methods as they can be used from anywhere, saves duplicating the code in many places and adds that nice syntactic sugar.

    Here's the same done without extension methods.

    Code (csharp):
    1. private void SetTextAlpha(Text text, float alpha)
    2. {
    3.   Color c = text.color;
    4.   c.a = alpha;
    5.   text.color = c;
    6. }
    I use a combination of LeanTween and a helper method to do my text fading - note I've got some extra code to handle outlines on the text (in case you're using those, shown below):

    Code (csharp):
    1. LeanTween.value(gameObject, 0, 1, fadeDuration).setOnUpdate(delegate(float v)
    2. {
    3.     SetTextAlpha(textObject, v); // uses the method shown above.
    4. });
    The version to fade Outlines also:

    Code (csharp):
    1. private void SetTextAlpha(Text text, float alpha)
    2. {
    3.     Color c = text.color;
    4.     c.a = alpha;
    5.     text.color = c;
    6.     float outLineAlpha = alpha*alpha*alpha;
    7.     Outline[] outlines = text.gameObject.GetComponents<Outline>();
    8.     for (int i = 0; i < outlines.Length; ++i)
    9.     {
    10.         Color oc = outlines[i].effectColor;
    11.         oc.a = outlineAlpha;
    12.         outlines[i].effectColor = oc;
    13.     }
    14. }
     
    Last edited: Jun 4, 2015
  3. tarzanno

    tarzanno

    Joined:
    Apr 23, 2015
    Posts:
    58
    Thanks for reply!
    This is the first time I see the extension class. My coding skills are very poor, but I'm trying to make things in practice without much theoretical knowlege.
    When I put
    Code (CSharp):
    1.     public static void SetAlpha(this Text text, float alpha)
    2.     {
    3.         Color c = text.color;
    4.         c.a = alpha;
    5.         text.color=c;
    6.        
    7.     }
    inside my TextReadFromFile script, I got the error: "error CS1106: `TextReadFromFile.SetAlpha(this UnityEngine.UI.Text, float)': Extension methods must be defined in a non-generic static class".

    And I actually don't know where and how should I make this alpha change value.

    I downloaded that LeanTween, I put
    Code (CSharp):
    1. LeanTween.value(gameObject, 0, 1, fadeDuration).setOnUpdate(delegate(float v)
    2.                                                                     {
    3.             text.SetAlpha(v); // uses the extension method shown above.
    4.         });
    into Start() method, and in text.SetAlpha(v) there is a problem "UnityEngine.UI.Text does not contain a definition for "SetAlpha"" I guess this occurs because of an error in that extension method.
     
  4. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    tarzanno likes this.
  5. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Hey tarzanno, I edited my previous post to provide a non extension method version. Though I'd suggest using the extension methods if you can as it just a little neater.

    To use extension methods just create a class like this and you can put any extension methods into it and use them from anywhere.

    Code (csharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4.  
    5. public static class CustomExtensionMethods
    6. {
    7.     public static void SetAlpha(this Text text, float alpha)
    8.     {
    9.       Color c = text.color;
    10.       c.a = alpha;
    11.       text.color = c;
    12.     }
    13.  
    14.    public static void SetAlphaWithOutlines(this Text text, float alpha)
    15.    {
    16.        Color c = text.color;
    17.        c.a = alpha;
    18.        text.color = c;
    19.        float outLineAlpha = alpha*alpha*alpha;
    20.        Outline[] outlines = text.gameObject.GetComponents<Outline>();
    21.        for (int i = 0; i < outlines.Length; ++i)
    22.        {
    23.            Color oc = outlines[i].effectColor;
    24.            oc.a = outlineAlpha;
    25.            outlines[i].effectColor = oc;
    26.        }
    27.    }
    28. }
     
    tarzanno likes this.
  6. tarzanno

    tarzanno

    Joined:
    Apr 23, 2015
    Posts:
    58
    Guys, you are the best. Thank you for that solution.
     
    larku likes this.