weird behavior on script

hello, guys!

i’m learning Unity cloning some simple games, right now i’m doing a color match game (from Lumosity)

it’s working okay, but if the player votes with one of the buttons and in the next iteration they vote with the other button, even if they selected the right answer the script is showing the wrongAnswerSprite

the buttons trigger the function:

  • No button triggers with bool guessed = false
  • Yes button triggers with bool guessed = true

the rest of the code is working perfectly fine, i’ve already debugged it

    public void Guessed(bool guessed) {
        if ((guessed == true && (colorMeaningCode == textColorColorCode)) || (guessed == false && (colorMeaningCode != textColorColorCode))) {
            textColorBox.gameObject.GetComponent<Image>().sprite = rightAnswerSprite;
        } else {
            textColorBox.gameObject.GetComponent<Image>().sprite = wrongAnswerSprite;
        }
        isAnswered = true;
    }

Try replacing the whole if-statement in your function with following:

bool isColorSame = (colorMeaningCode == textColorColorCode);
textColorBox.gameObject.GetComponent<Image>().sprite = (guessed == isColorSame) ? rightAnswerSprite : wrongAnswerSprite;

still having the same issue =/

if I vote with one of the buttons and in the next iteration I vote with the other button, even if I’ve selected the right answer the script shows the wrongAnswerSprite → from the second interaction with the other button it goes back to normal, until I need to switch buttons again

That’s weird… If colorMeaningCode and textColorColorCodeare are both colors, could you please provide the code where their color is set? And what are you doing with isAnswered after the function is invoked? If you say that it gets back to normal after every second answer, the state of isAnswered might also couse the issue…

I will provide the entire script for you to get all the context (probably there is some bad practices and unoptimized stuff, but that’s because I’m a beginner)

public class ShowColor : MonoBehaviour {

    public GameObject colorMeaningTextObject;
    public GameObject textColorTextObject;
    public GameObject textColorBox;
    public Sprite rightAnswerSprite;
    public Sprite wrongAnswerSprite;
    public Sprite defaultSprite;

    // Start is called before the first frame update
    void Start() {
        isAnswered = true;
        textColorBox.gameObject.GetComponent<Image>().sprite = defaultSprite;
    }

    readonly int yellow = 1;
    readonly int blue = 2;
    readonly int red = 3;
    readonly int green = 4;
    readonly int gray = 5;
    readonly int white = 6;
    readonly int pink = 7;

    int colorMeaningCode;
    int textColorMeaningCode;
    int textColorColorCode;

    bool isAnswered = false;

    private void NewRandomNumbers() {
        colorMeaningCode = Random.Range(1, 8);
        textColorColorCode = Random.Range(1, 8);
        textColorMeaningCode = Random.Range(1, 8);
    }

    public void NewTextColors() {


        colorMeaningCode = 0;
        textColorMeaningCode = 0;
        textColorColorCode = 0;

        Text colorMeaning = GameObject.Find("colorMeaningText").GetComponent<Text>();
        Text textColor = GameObject.Find("textColorText").GetComponent<Text>();

        isAnswered = false;

        NewRandomNumbers();

        SortNewColorMeaning(colorMeaning);
        SortNewTextColorMeaning(textColor);
        SortNewTextColor(textColor);

    }

    private void SortNewColorMeaning(Text colorMeaning) {
        if (colorMeaningCode == yellow) {
            colorMeaning.text = "amarelo";
        } else if (colorMeaningCode == blue) {
            colorMeaning.text = "azul";
        } else if (colorMeaningCode == red) {
            colorMeaning.text = "vermelho";
        } else if (colorMeaningCode == green) {
            colorMeaning.text = "verde";
        } else if (colorMeaningCode == gray) {
            colorMeaning.text = "cinza";
        } else if (colorMeaningCode == white) {
            colorMeaning.text = "branco";
        } else if (colorMeaningCode == pink) {
            colorMeaning.text = "rosa";
        }
    }

    private void SortNewTextColorMeaning(Text textColor) {
        if (textColorMeaningCode == yellow) {
            textColor.text = "amarelo";
        } else if (textColorMeaningCode == blue) {
            textColor.text = "azul";
        } else if (textColorMeaningCode == red) {
            textColor.text = "vermelho";
        } else if (textColorMeaningCode == green) {
            textColor.text = "verde";
        } else if (textColorMeaningCode == gray) {
            textColor.text = "cinza";
        } else if (textColorMeaningCode == white) {
            textColor.text = "branco";
        } else if (textColorMeaningCode == pink) {
            textColor.text = "rosa";
        }
    }

    private void SortNewTextColor(Text textColor) {
        if (textColorColorCode == yellow) {
            textColor.color = new Color(1, 0.9f, 0, 1);
        } else if (textColorColorCode == blue) {
            textColor.color = new Color(0.14f, 0.14f, 1, 1);
        } else if (textColorColorCode == red) {
            textColor.color = new Color(1, 0.1f, 0.1f, 1);
        } else if (textColorColorCode == green) {
            textColor.color = new Color(0, 0.8f, 0, 1);
        } else if (textColorColorCode == gray) {
            textColor.color = new Color(0.5f, 0.5f, 0.5f, 1);
        } else if (textColorColorCode == white) {
            textColor.color = new Color(1, 1, 1, 1);
        } else if (textColorColorCode == pink) {
            textColor.color = new Color(1, 0, 0.5f, 1);
        }
    }

    public void Guessed(bool guessed) {
        /*if ((guessed == true && (colorMeaningCode == textColorColorCode)) || (guessed == false && (colorMeaningCode != textColorColorCode))) {
            textColorBox.gameObject.GetComponent<Image>().sprite = rightAnswerSprite;
        } else {
            textColorBox.gameObject.GetComponent<Image>().sprite = wrongAnswerSprite;
        }*/
        bool isColorSame = (colorMeaningCode == textColorColorCode);
        textColorBox.gameObject.GetComponent<Image>().sprite = (guessed == isColorSame) ? rightAnswerSprite : wrongAnswerSprite;
        isAnswered = true;
    }

    // Update is called once per frame
    void Update()
    {
        if (isAnswered) {
            NewTextColors();
        }
    }
}

I optimized some of your code and debugged the Guessed() function, and it worked. Sure that no other component is changing the sprite?

Here’s the code:

    public class ShowColor : MonoBehaviour
    {
        #region Variables
        public GameObject colorMeaningTextObject;
        public GameObject textColorTextObject;
        public GameObject textColorBox;
        public Sprite rightAnswerSprite;
        public Sprite wrongAnswerSprite;
        public Sprite defaultSprite;

        readonly List<KeyValuePair<int, string>> colors = new List<KeyValuePair<int, string>>()
        {
            new KeyValuePair<int, string>(1, "amarelo"),
            new KeyValuePair<int, string>(2, "azul"),
            new KeyValuePair<int, string>(3, "vermelho"),
            new KeyValuePair<int, string>(4, "verde"),
            new KeyValuePair<int, string>(5, "cinza"),
            new KeyValuePair<int, string>(6, "branco"),
            new KeyValuePair<int, string>(7, "rosa"),
        };
        readonly List<Color> textColors = new List<Color>()
        {
            new Color(1, 0.9f, 0, 1),
            new Color(0.14f, 0.14f, 1, 1),
            new Color(1, 0.1f, 0.1f, 1),
            new Color(0, 0.8f, 0, 1),
            new Color(0.5f, 0.5f, 0.5f, 1),
            new Color(1, 1, 1, 1),
            new Color(1, 0, 0.5f, 1)
        };

        int colorMeaningCode;
        int textColorMeaningCode;
        int textColorColorCode;

        bool isAnswered = false;
        Image clrBoxImg = null;
        #endregion

        void Awake() => clrBoxImg = textColorBox.gameObject.GetComponent<Image>();
        void Start()
        {
            clrBoxImg.sprite = defaultSprite;
            NewTextColors();
        }

        void NewTextColors()
        {
            isAnswered = false;

            Text colorMeaning = GameObject.Find("colorMeaningText").GetComponent<Text>();
            Text textColor = GameObject.Find("textColorText").GetComponent<Text>();

            colorMeaningCode = Random.Range(1, 8);
            textColorColorCode = Random.Range(1, 8);
            textColorMeaningCode = Random.Range(1, 8);

            foreach (var item in colors)
            {
                if (item.Key == colorMeaningCode) colorMeaning.text = item.Value;
                if (item.Key == textColorMeaningCode) textColor.text = item.Value;
                if (item.Key == textColorColorCode) textColor.color = textColors[item.Key];
            }
        }
        public void Guessed(bool guessed)
        {
            bool isColorSame = colorMeaningCode == textColorColorCode;
           clrBoxImg.sprite = (guessed == isColorSame) ? rightAnswerSprite :                     wrongAnswerSprite;
            isAnswered = true;
        }

        void Update()
        {
            if (isAnswered)
            {
                NewTextColors();
                isAnswered = false;
            }
        }
    }
1 Like

if it is, i can’t see where

i’ve submitted the project to a github repository, but I don’t know if is allowed to share a link to it here, is it?

also: when i replace the code to your’s it stops working with this error message:

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

Yes you can post it here

access repository on github

Ok, I downloaded your repo. Change

if (item.Key == textColorColorCode) textColor.color = textColors[item.Key]; // line189

to

if (item.Key == textColorColorCode) textColor.color = textColors[item.Key - 1];

and it should work. At least after that your game works completely fine after I tested it!

thanks for the optimization, I will study it to learn :slight_smile:

but that issue with the feedback color (on when the player got it correct or not) - you played and saw what i was talking about?

when you switch buttons it shows the red color (wrongAnswerSprite) even if you have selected the right answer

att: now i’ve noticed that it is only happening when you press yes button after pressing no button on the “previous round” - before you optimized, it was happening the other way too

The sprite switched over to green when it was right and to red when false. I also debugged your code, there’s nothing wrong with that, and no other components are changing it while runtime.

The last thing that I’d think causing the problem would be the text displaying incorrect colors. Because when debugging, the sprite changed to green when both integers were the same, even when the visual was wrong.

Another fix would be probably changing lines from 53 to 63 to following:

            foreach (var item in colors)
            {
                if (item.Key == colorMeaningCode) 
                {   
                    colorMeaning.text = item.Value;
                    textColors[item.Key - 1]
                }
                if (item.Key == textColorMeaningCode) textColor.text = item.Value;
            }

Can’t guarantee anything :open_mouth:

i really appreciate you trying to help me, thanks

i’ve changed to your suggestion (just needed to add some code that i think you missed on line 4) and that issue has stopped

but now:

  • 100% of the time it is sorting correct correlations between color meaning and text color;

  • it is showing the red sprite when we get the correct answer (but that’s probably easy to fix, just invert somewhere);

  • ~1/10 times it shows the other sprite even if i’m only pressing the yes button and getting right answers (because of the first issue of the list).

maybe some of these new issues have come because i’ve completed your suggestion wrongly?

foreach (var item in colors) {
                if (item.Key == colorMeaningCode) {
                    colorMeaning.text = item.Value;
                    textColor.color = textColors[item.Key - 1];
                }
                if (item.Key == textColorMeaningCode) textColor.text = item.Value;
            }

When I changed that code I noticed that there are actually 3 int variables, but you only need 2 - one for the textcolor and the other one for the text itself. The third one always made the text color random, ignoring the other two values, which were compared in Guessed(). Thats maybe why the visual is displayed wrong but the other two values colorMeaningCode textColorColorCode are correct in code. Everything works fine, but actually just the color of your text is displayed wrongly.

i finally fixed it!

i don’t know why, but with mouse-click, i was getting that issue. getting the input by keyboard keys fixed it

thank you for helping me!

void Update() {
    if (isAnswered) {
        NewTextColors();
        isAnswered = false;
    }
    if (Input.GetKeyDown(KeyCode.RightArrow)) {
        Guessed(true);
    } else if (Input.GetKeyDown(KeyCode.LeftArrow)) {
        Guessed(false);
    }
}