macintosh
macintosh

Reputation: 161

Unity Showing multiple images in UI with the Coroutine

I have four integer variable that affects the final result of the game.

When the game finishes the variables slide 0 to max number with Time.deltaTime(it takes 5-8 sec)

Then after all four variables reach the player max score then I am showing two different pages (Won/Lost)

So far everything works well so when the result changes the final Image changes as well.

My problem is I want to put a third picture while number slide to up (waiting page!)

but I cannot see the third page. I used the inspector and tried almost every possibility but I cannot see the third picture.

Here is my code:

using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;

public class EndGameStat : MonoBehaviour {
    public Text AppearanceStatText;
    public Text LikeabilityStatText;
    public Text MannerismsStatText;
    public Text HumanityStatText;
    public Text ResultText;
    public Text StoryResultText;
    public Image failImage;
    public Image SuccessImage;
    public Image WaitingImage;
    public Sprite failImageSprite;
    public Sprite successImageSprite;
    public Sprite WaitingImageSprite;

    public static float AppearanceStat = 0;
    public static float LikeabilityStat = 0;
    public static float MannerismsStat = 0;
    public static float HumanityStat = 0;

    public static int AppearanceStatFinal = 70;
    public static int LikeabilityStatFinal = 40;
    public static int MannerismsStatFinal = 90;
    public static int HumanityStatFinal = 30;

    public static int intialNumber;
    public static int animationTime = 3;

    public static float avg = (AppearanceStatFinal + LikeabilityStatFinal + MannerismsStatFinal) / 3;

    Color maxColor = new Color32 (20, 200, 20, 255);
    Color minColor = new Color32 (250, 10, 0, 255);

    // Start is called before the first frame update
    void Start () {

        AppearanceStatText.text = AppearanceStat.ToString ();
        LikeabilityStatText.text = LikeabilityStat.ToString ();
        MannerismsStatText.text = MannerismsStat.ToString ();
        HumanityStatText.text = HumanityStat.ToString ();

    }

    // Update is called once per frame
    void Update () {

        if (AppearanceStatFinal != AppearanceStat) {

            AppearanceStat += (animationTime * Time.deltaTime);
            AppearanceStatText.text = AppearanceStat.ToString ("f0");
            AppearanceStatText.GetComponent<Text> ().color = Color.Lerp (minColor, maxColor, AppearanceStat / 100f);
            if (AppearanceStat > AppearanceStatFinal)
                AppearanceStat = AppearanceStatFinal;

        }

        if (LikeabilityStatFinal != LikeabilityStat) {

            LikeabilityStat += (animationTime * Time.deltaTime);
            LikeabilityStatText.text = LikeabilityStat.ToString ("f0");
            LikeabilityStatText.GetComponent<Text> ().color = Color.Lerp (minColor, maxColor, LikeabilityStat / 100f);
            if (LikeabilityStat > LikeabilityStatFinal)
                LikeabilityStat = LikeabilityStatFinal;

        }

        if (MannerismsStatFinal != MannerismsStat) {

            MannerismsStat += (animationTime * Time.deltaTime);
            MannerismsStatText.text = MannerismsStat.ToString ("f0");
            MannerismsStatText.GetComponent<Text> ().color = Color.Lerp (minColor, maxColor, MannerismsStat / 100f);
            if (MannerismsStat > MannerismsStatFinal)
                MannerismsStat = MannerismsStatFinal;

        }

        if (HumanityStatFinal != HumanityStat) {

            HumanityStat += (animationTime * Time.deltaTime);
            HumanityStatText.text = HumanityStat.ToString ("f0");
            HumanityStatText.GetComponent<Text> ().color = Color.Lerp (minColor, maxColor, HumanityStat / 100f);
            if (HumanityStat > HumanityStatFinal)
                HumanityStat = HumanityStatFinal;

        }

        StartCoroutine (resultPage ());

    }
    bool CDPage () {

        if (HumanityStat == HumanityStatFinal & MannerismsStat == MannerismsStatFinal & LikeabilityStat == LikeabilityStatFinal & AppearanceStat == AppearanceStatFinal) {

            return true;

        } else {

            return false;

        }
    }

    IEnumerator resultPage () {

        yield return new WaitUntil (CDPage);

        if (avg < 50) {
            ResultText.text = "FAIL!";
            StoryResultText.text = "You are not belong here";
            failImage.sprite = failImageSprite;
            SuccessImage.enabled = false;

        } else {
            ResultText.text = "SUCCESS";
            StoryResultText.text = "Welcome!!";
            SuccessImage.sprite = successImageSprite;
            failImage.enabled = false;

        }

    }

}

Can you help me to find my error?

Update: enter image description here

Upvotes: 0

Views: 111

Answers (1)

derHugo
derHugo

Reputation: 90724

After your update I think what you want would be something like

private void Awake(){
    // enough to do these only once
    WaitingImage.sprite = WaitingImageSprite;
    failImage.sprite = failImageSprite;
    SuccessImage.sprite = successImageSprite;
}

IEnumerator resultPage () 
{
    WaitingImage.enabled = true;
    SuccessImage.enabled = false;
    failImage.enabled = false;

    yield return new WaitUntil (CDPage);

    if (avg < 50) {
        ResultText.text = "FAIL!";
        StoryResultText.text = "You are not belong here";
        failImage.enabled = true;
    } else {
        ResultText.text = "SUCCESS";
        StoryResultText.text = "Welcome!!";
        SuccessImage.enabled = true;
    }

}

besides that as already mentioned: All these GetComponent<Text> calls are redundant and you can simply use e.g.

AppearanceStatText.color = ...;

and note that your Update method is constantly calling a new StartCoroutine(resultPage()); each frame. So you get a bunch of concurrent routines. You should either skip it in case a routine is already running or maybe start the routine in Start only once.

Also why are you using static there? If these are constants rather make them const.

Actually I would simply move the entire code to a coroutine like

// yes, Start itself can be a coroutine ;)
void IEnumerator Start () 
{
    WaitingImage.enabled = true;
    SuccessImage.enabled = false;
    failImage.enabled = false;

    AppearanceStatText.text = AppearanceStat.ToString ();
    LikeabilityStatText.text = LikeabilityStat.ToString ();
    MannerismsStatText.text = MannerismsStat.ToString ();
    HumanityStatText.text = HumanityStat.ToString ();

    while(HumanityStat != HumanityStatFinal || MannerismsStat != MannerismsStatFinal || LikeabilityStat != LikeabilityStatFinal || AppearanceStat != AppearanceStatFinal
    {
        if (AppearanceStatFinal != AppearanceStat) 
        {
            AppearanceStat += (animationTime * Time.deltaTime);
            // do your clamping first, then set the color and update the text
            if (AppearanceStat > AppearanceStatFinal) AppearanceStat = AppearanceStatFinal;
            AppearanceStatText.text = AppearanceStat.ToString ("f0");
            AppearanceStatText.color = Color.Lerp (minColor, maxColor, AppearanceStat / 100f);
        }

        //TODO EQUALLY FOR THE OTHER 4 TEXTS AND ACCORDING VALUES

        // finally wait for the next frame here
        yield return null;
    }

    // finally do your check    

    if (avg < 50) 
    {
        ResultText.text = "FAIL!";
        StoryResultText.text = "You are not belong here";
        failImage.enabled = true;
    } 
    else 
    {
        ResultText.text = "SUCCESS";
        StoryResultText.text = "Welcome!!";
        SuccessImage.enabled = true;
    }
}

Upvotes: 1

Related Questions