0
\$\begingroup\$

On my quest to understand Unity in a zero to hero sort of manner, I've run into a new problem I can't seem to really solve.

From computer science I know that updating GUI on the same thread as everything else is the worst thing you can do, so naturally I'd like to start a separate thread to update GUI Elements. I am not sure if this is how you are supposed to do it in Unity, or if it takes care of that on it's own but my guess is it doesn't.

So I went to Google and after a bit I found Color.Lerp(Color,Color,float) which seemed to do the job nicely. But applying it as a function over time have been harder than I anticipated. Below you see my code:

using UnityEngine;
using System.Collections;

public class GUITextTriggerController : MonoBehaviour
{
    public GUIText guiText;
    public float fadeDuration;
    private bool IsTriggered;

    public void Start()
    {
        guiText.color = new Color(1.0f, 1.0f, 1.0f, 0.0f);
        IsTriggered = false;
    }

    void OnTriggerEnter(Collider other)
    {
        if (IsTriggered == false)
        {
            IsTriggered = true;
            StartCoroutine(UpdateTextColor());
        }
    }

    IEnumerator UpdateTextColor()
    {
        yield return new WaitForEndOfFrame(); // So that I return something at least.
        float t = 0;
        while (t < 1)
        {
            guiText.color = Color.Lerp(new Color(1.0f, 1.0f, 1.0f, 0.0f), new Color(1.0f, 1.0f, 1.0f, 1.0f), t);
            t += Time.deltaTime / fadeDuration;
        }
    }
}

My understanding of Unity is still very much beginner so bear with me. From my understanding, using Co-routines and yield is essentially Unity's answer to Threading (correct me if I am wrong) so I thought the above could do the trick but rather than changing over time, the texts color changes instantly as soon as I enter my trigger volume.

\$\endgroup\$
1
\$\begingroup\$

Really really simple. Actually you are using while loop just like a regular loop despite of being in Coroutine.

You did a small mistake, although it is necessary to return yield in Coroutine and that is for a reason and the matter of fact is, it will bring that in another thread.

In other words, yield return new WaitForEndOfFrame(); works like execute all the code above this line, let pointer leave Coroutine for the specific time (time of a frame) and then come back and execute the remaining code.

Now if you can see, what you did is just yield return once, by that, all the remaining code will execute in regular manner.

What you can do is just move yield return new WaitForEndOfFrame(); inside while so that it can slow down the loop.

IEnumerator UpdateTextColor()
{
    float t = 0;
    while (t < 1)
    {
        // Now the loop will execute on every end of frame until the condition is true
        guiText.color = Color.Lerp(new Color(1.0f, 1.0f, 1.0f, 0.0f), new Color(1.0f, 1.0f, 1.0f, 1.0f), t);
        t += Time.deltaTime / fadeDuration;
        yield return new WaitForEndOfFrame(); // So that I return something at least.
    }
}
\$\endgroup\$

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.