Quiz Master - Unity Tutorial - Answers Coming Up Incorrect

Hello,

When I try running my game, the questions are coming up as incorrect on 7/8 of them. I have checked in the inspector that I have the correct element selected as the answer. I have also tried selecting the other 3 incorrect answers to see if they would register as the correct answer for some reason, however; they do not. I am not really certain on the code error as I think it all looks similar to the instructors. Any assistance would be greatly appreciated.

Below is my my quiz script as reference:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using TMPro;

using UnityEngine.UI;

public class Quiz : MonoBehaviour

{

[Header("Questions")]

[SerializeField] TextMeshProUGUI questionText;

[SerializeField] List questions = new List ();

QuestionSO currentQuestion;

[Header(“Answers”)]

bool hasAnsweredEarly;

[SerializeField] GameObject answerButtons;

int correctAnswerIndex;

[Header(“Button Colors”)]

[SerializeField] Sprite defaultAnswerSprite;

[SerializeField] Sprite correctAnswerSprite;

[Header(“Timer”)]

[SerializeField] Image timerImage;

Timer timer;

[Header (“Scoring”)]

[SerializeField] TextMeshProUGUI scoreText;

ScoreKeeper scoreKeeper;

void Start()

{

timer = FindObjectOfType();

scoreKeeper = FindObjectOfType();

}

void Update()

{

timerImage.fillAmount = timer.fillFraction;

if (timer.LoadNextQuestion)

{

    hasAnsweredEarly = false;

    GetNextQuestion();

    timer.LoadNextQuestion = false;

}

else if (!hasAnsweredEarly && !timer.isAnsweringQuestion)

{

    DisplayAnswer(-1);

    SetButtonState (false);

}

}

public void OnAnswerSelected(int index)

{

hasAnsweredEarly = true;

DisplayAnswer (index);

SetButtonState(false);

timer.CancelTimer();

scoreText.text = "Score: " + scoreKeeper.CalculateScore() + “%”;

}

void DisplayAnswer (int index)

{

Image buttonImage;

if (index == currentQuestion.GetCorrectAnswerIndex())

{

questionText.text = "Correct";

buttonImage = answerButtons [index]. GetComponent<Image>();

buttonImage.sprite = correctAnswerSprite;

scoreKeeper.IncrementCorrectAnswers();

}

else

{

correctAnswerIndex = currentQuestion.GetCorrectAnswerIndex();

string correctAnswer = currentQuestion.GetAnswer (correctAnswerIndex);

questionText.text = “Sorry, the correct answer was; \n” + correctAnswer;

buttonImage = answerButtons [correctAnswerIndex]. GetComponent();

buttonImage.sprite = correctAnswerSprite;

}

}

void GetNextQuestion()

{

    if (questions.Count > 0)

    {

    SetButtonState(true);

    SetDefaultButtonSprites();

    GetRandomQuestion();

    DisplayQuestion();

    scoreKeeper.IncrementQuestionsSeen();

    }

}

void GetRandomQuestion()

{

int index = Random.Range (0, questions.Count);

currentQuestion = questions [index];

if (questions.Contains(currentQuestion))

{

    questions.Remove(currentQuestion);

}

}

void DisplayQuestion()

{

questionText.text = currentQuestion.GetQuestion();  

for (int i = 0; i < answerButtons.Length; i++)

{

TextMeshProUGUI buttonText = answerButtons[i].GetComponentInChildren<TextMeshProUGUI>();  

buttonText.text = currentQuestion.GetAnswer(i);

}

}

void SetButtonState(bool state)

{

 for (int i = 0; i < answerButtons.Length; i++)

 {

     Button button = answerButtons [i].GetComponent<Button>();

     button.interactable = state;

 }  

}

void SetDefaultButtonSprites()

{

for (int i = 0; i < answerButtons.Length; i++)

{

    Image buttonImage = answerButtons[i].GetComponent<Image>();

    buttonImage.sprite = defaultAnswerSprite;

}

}

}

Hi Tadpho,

Welcome to our community! :slight_smile:

Please note, it’s better to copy/paste your code and apply the code fencing characters, rather than using screenshots. Screenshots are ideal for displaying specific details from within a game engine editor or even error messages, but for code, they tend to be less readable, especially on mobile devices which can require extensive zooming and scrolling.

You also prevent those that may offer to help you the ability to copy/paste part of your code back to you with suggestions and/or corrections, meaning that they would need to type a potentially lengthy response. You will often find that people are more likely to respond to your questions if you make it as easy as possible for them to do so.

Have you already tried to add Debug.Logs to your code to see what is going on during runtime?

Hope this helps :slight_smile:


See also;

Hello Nina,

Thank you for the advice. For starters, I have copy and pasted my script for ease of reference. I will keep that in mind for future posting!

I tried the debug.log in the following part of the script to test it out:

void DisplayAnswer (int index)
{
    Image buttonImage;

    if (index == currentQuestion.GetCorrectAnswerIndex())
    {
        Debug.Log ("Wow!");

        questionText.text = "Correct";
        buttonImage = answerButtons [index]. GetComponent<Image>();
        buttonImage.sprite = correctAnswerSprite;
        scoreKeeper.IncrementCorrectAnswers();
    }
    else
    {
        correctAnswerIndex = currentQuestion.GetCorrectAnswerIndex();
        string correctAnswer = currentQuestion.GetAnswer (correctAnswerIndex);
        questionText.text = "Sorry, the correct answer was; \n" + correctAnswer;
        buttonImage = answerButtons [correctAnswerIndex]. GetComponent<Image>();
         buttonImage.sprite = correctAnswerSprite;
    }
}

The text activated in the console on 1 out of the 8 questions, which is odd. Is there other troubleshooting methods you would recommend?

Thanks again! :slightly_smiling_face:

Maybe you could start with checking the OnClick fields of your buttons. According to Gary’s concept, each button passes on an integer to the method that gets called on button click. Each integer refers to an “answer index” in your QuestionSO object. Maybe they have the same values or the wrong values.

And you also have to define a correct answer index in your QuestionSO objects.

Hello Nina,

So I believe I have determined the issue, but i’m still struggling on how to troubleshoot it. It appears that the only answer that’s working was set to element 0. When I set another questions correct answer to element 0 it worked. I believe in this case the index is not working properly.

Here is my script for the QuestionSO:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(menuName = "Quiz Question", fileName = "New Question")]
public class QuestionSO : ScriptableObject
{
    [TextArea (2, 6)]
    [SerializeField] string question = "Enter new question text here";

    [SerializeField] string[x] answers = new string[4];
    [SerializeField] int correctAnswerIndex;

    public string GetQuestion()
    {
        return question;
    }

    public string GetAnswer (int index)
    {
        return answers[index];
    }

    public int GetCorrectAnswerIndex()
    {
        return correctAnswerIndex;
    }
}

Good job on analysing the problem. :slight_smile:

Is there really an x in string[x] answers = new string[4];? Sometimes, the forum makes characters disappear which is why it is important to format the code properly.

What you could do is adding Debug.Logs to the respective methods to see what value they receive. For example:

public string GetAnswer (int index)
{
    Debug.Log("GetAnswer value: " + index);
    return answers[index];
}

If all calls of the GetAnswer method return the same value, the problem is the answers array. In that case, you would have to check the concerning QuestionSO object.

You figured out that only element 0 was working. This sounds as if the value of correctAnswerIndex does not match the “correct” answer index in the answers array of the respective QuestionSO object.

You could do something similar in the DisplayAnswer method:

void DisplayAnswer (int index)
{
    Debug.Log("DisplayAnswer value: " + index);
    // your code
}

If this method returns the same value even though you expected different values, check where this method gets called and where the value for index stems from.

Just to ensure we are talking about the same: Our answers are in the answers array. Let’s say our correct answer is element 3 (= index 2). In that case, we would have to assign 2 to correctAnswerIndex. When clicking the third button in our game, that button should pass on 2 to the method it calls. And that value would be equal the value of correctAnswerIndex. The other buttons pass on other values, which are not equal the value of correctAnswerIndex. That’s the entire logic of this game regarding the selection of a “correct” or “wrong” answer.


And if that didn’t help you narrowing down the problem further, add a few more Debug.Logs in a similar way. Debugging is not difficult, it’s just fairly repetitive. Try to reenact the “rules” of the game by adding Debug.Logs and verify/falsify your assumptions by interpreting the information you log into your console. Never assume that something works just because it looks as if it was working or should be working. A lot is going on during runtime. :slight_smile:

Hello Nina,

Thank you for your assistance so far. This project on the course appears to of been a bit too difficult for my skill level. I am hoping to work through the remainder of this project, then return to the course once I get a bit more coding knowledge :slight_smile:

There is no x in string[x] answers = new string[4];. The ‘x’ seems to have generated for some reason upon posting in the forum. I will try to keep that in mind for future posts as well.

I first tried adding, as you suggested, Debug.Log to the GetAnswer method, and I received different values, so that appears to be working properly.

When I added the Debug.Log to the DisplayAnswer method however, the values all came back the same. I think this method gets called from the OnAnswerSelected method, so I tried adding the Debug.Log there to see what would happen:

public void OnAnswerSelected(int index)

{

Debug.Log("DisplayAnswer value: " + index);

hasAnsweredEarly = true;

DisplayAnswer (index);

SetButtonState(false);

timer.CancelTimer();

scoreText.text = "Score: " + scoreKeeper.CalculateScore() + “%”;

}

The values came back all the same here as well. At the end it also displayed a null reference exception, which I assume is due to the error of adding the Debug.Log in this location.

I am very lost on where I go from here. I apologize for reaching out again for assistance. Like I mentioned, I think I bit off more then I can chew with this specific project, and I plan to come back to this course once I get a bit more coding knowledge.

Thank you again! :slight_smile:

Same values? That’s great.

Are you sure that the OnAnswerSelected method logged the values into your console? I’m asking because the message inside the parentheses of the Debug.Log method says “DisplayAnswer”.

Assuming the OnAnswerSelected method did log the same value, do the following:

public void OnAnswerSelected(int index)
{
    Debug.Log("OnAnswerSelected value: " + index);
    return;

    // rest of your code
}

return; terminates the method immediately. When testing “nothing” will happen in your game but messages will appear in your console. That’s what we want because we want to take a look at this specific event without the complex rest of the game logic.

In play mode, click on all buttons to see what values they return. If they return the same value (e.g. only 0 for all buttons), stop the game because you found the problem.

Click on the first button game object in your Hierarchy and check its OnClick field. That field should be connected with the OnAnswerSelected method. The value defined inside the OnClick value field that gets passed on to the OnAnswerSelected should be 0.

If that’s correct, select the second button. It’s value should be 1.
Then select the third button. It’s value should be 2.
And so on.

If you had to change the values, click on Play and test your game again. If the OnAnswerSelected logs different values into your console, stop your game and remove return; from your code. Save your script and test your game again. Theoretically, it should work then.

Hello Nina,

Thank you for your help! It works! :slight_smile:

I was so hell bent on finding the error in how the code was written I didn’t realize that when I duplicated the first answer button in the Unity hierarchy, I didn’t set the number for the other buttons when they were selected.

It is all working now, thanks again! :grinning_face_with_smiling_eyes:

Fantastic. I’m glad you found and fixed the problem. :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms