0
\$\begingroup\$

I have a prefab m_wordContainer which is empty other than having a TextMeshProUGUI as a child (I did this so that I could position this container freely not being bugged by an animation played by the TMPUGUI object). At the start of the program I start a coroutine (SpawnWordPopups) which splits the words in a sentence, making a copy of m_wordContainer and assigning that word to the text property of its TMPUGUI, spawning such m_wordContainer in a random location within the screen, and then starting a coroutine (FadeText) that fades in the text of every TMPUGUI. The problem is that only one of the TMPUGUI has its text faded, even though the FadeText coroutine is called seemingly correctly. All words are shown as expected, only thing missing is the fading effect on all but the first word that fades. If I called FadeText like this: if (i > 0) { yield return FadeText(true, tmpText, 2); } then only the second word will be faded.

 [SerializeField] private GameObject m_wordContainer;
 
    void Start()
    {
        yield return StartCoroutine(SpawnWordPopups("test foo bar"));
    }
 
private IEnumerator SpawnWordPopups(string l_line)
    {
        string[] words = l_line.Split(' ');
        List<Vector3> wordPositions = new List<Vector3>();
        for (int i = 0; i < words.Length; ++i)
        {
            Vector3 spawnLocation = new Vector3(Random.Range(m_wordScreenDistanceOffset, Screen.width - m_wordScreenDistanceOffset), Random.Range(m_wordScreenDistanceOffset, Screen.height - m_wordScreenDistanceOffset), 0);
            if (IsWordOverlapping(wordPositions, spawnLocation))
            {
                --i;
                continue;
            }
            wordPositions.Add(spawnLocation);
            GameObject wordContainer = Instantiate(m_wordContainer, transform.parent);
            wordContainer.transform.position = spawnLocation;
            TextMeshProUGUI tmpText = wordContainer.GetComponentInChildren<TextMeshProUGUI>();
            tmpText.text = words[i];
 
            yield return FadeText(true, tmpText, 2);
        }
    }
 
    private IEnumerator FadeText(bool l_fadeIn, TextMeshProUGUI l_textBox, float l_time)
    {
        float time = Time.time;
        float until = Time.time + l_time;
        int alphaFrom = l_fadeIn ? 0 : 1;
        int alphaGoal = l_fadeIn ? 1 : 0;
        Color textColor = l_textBox.color;
        textColor.a = l_fadeIn ? 0 : 1;
        l_textBox.color = textColor;
 
        while (time < until)
        {
            textColor = l_textBox.color;
            textColor.a = Mathf.Lerp(alphaFrom, alphaGoal, Time.time / l_time);
            l_textBox.color = textColor;
            time += Time.deltaTime;
            yield return null;
        }
        textColor.a = l_fadeIn ? 1 : 0;
        l_textBox.color = textColor;
    }

Could anyone shed some light into this issue I'm having? Why are not all the words being faded?

\$\endgroup\$
1
  • \$\begingroup\$ It's more of a preference thing, but standard convention for C# is not to apply scope prefixes like m_ and l_ to your variable names. A good modern IDE should eliminate the need for these prefixes, and they make typing a lot more of a hassle due to the awkward placement of the underscore on most keyboards. \$\endgroup\$
    – Kevin
    Aug 14 '20 at 0:07
0
\$\begingroup\$

I think the problem is the equation you're using for the t argument of Mathf.Lerp:

Time.time / l_time

Let's say your game has been running for 10 seconds. Then Time.time is 10, but l_time is 2, so your t is 10 / 2 = 5 which gets clamped to 1. What you should have written is (Time.time - time) / startTime. Your time-tracking solution is also messy in general. Here's the whole function with additional improvements:

private IEnumerator FadeText(bool l_fadeIn, TextMeshProUGUI l_textBox, float l_duration)
{
    float start = Time.time; //clearer name
    float until = start  + l_duration;
    int alphaFrom = l_fadeIn ? 0 : 1;
    int alphaGoal = 1 - alphaFrom;
    Color textColor = l_textBox.color;
    //removed redundant code here

    while (Time.time < until) //simplified
    { //don't need to keep reading the color from the text field each frame
        textColor.a = Mathf.Lerp(alphaFrom, alphaGoal, (Time.time - start) / l_duration);
        l_textBox.color = textColor;
        yield return null;
    }
    textColor.a = alphaGoal; //no need to recalculate the value
    l_textBox.color = textColor;
}
\$\endgroup\$
2
  • \$\begingroup\$ That was it, thank you so much! A lot of redundant lines were added in desperation trying to find the issue but never even thought about that equation that way, silly of me. Cheers! \$\endgroup\$
    – aramos
    Aug 14 '20 at 19:48
  • \$\begingroup\$ @aramos Great, glad to help! \$\endgroup\$
    – Kevin
    Aug 14 '20 at 20:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.