hae i have been following along the unity 2d game development series ,after the slider i noticed that in my game GetNextQuestion is called twice during start of the game, how to solve this issue
Hi Johnathan,
Welcome to our community!
How did you figure out that GetNextQuestion is called twice when the game starts? Did you use a Debug.Log? If so, check where your code could call GetNextQuestion and check with Debug.Logs which code-block gets called when the game starts.
Make sure there is only one Quiz component in your scene.
Hi,Nina,
Once i implimented slider and run the game slider value started at 2 and i used Debug.log to print a statement in GetQuestion() and GetRandomQuestion() both the methods gets called twice and both the methods are referenced only once in the code ,
Things i have tried so for ,
1.) Manually inspected each game object in hierarchy for duplicate quiz.cs but found no duplicates,
2.) Inspected every line of code with the source code from gitlab and both are same,
3.)also tried find references in scene on Quiz script shows only quiz canvas and
answer buttons
//this is quiz.cs
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<QuestionSO> questions = new List<QuestionSO>();
QuestionSO currentQuestion;
[Header("Answers")]
[SerializeField] GameObject[] answerButtons;
int correctAnswerIndex;
bool hasAnsweredEarly = true;
[Header("Button Colors")]
[SerializeField] Sprite defaultAnswerSprite;
[SerializeField] Sprite correctAnswerSprite;
[Header("Timer")]
[SerializeField] Image timerImage;
Timer timer;
[Header("Scoring")]
[SerializeField] TextMeshProUGUI scoreText;
ScoreKeeper scoreKeeper;
[Header("ProgressBar")]
[SerializeField] Slider progressBar;
public bool isComplete;
void Start()
{
Debug.Log("start");
timer = FindObjectOfType<Timer>();
scoreKeeper = FindObjectOfType<ScoreKeeper>();
progressBar.maxValue = questions.Count;
progressBar.value = 0;
}
void Update()
{
timerImage.fillAmount = timer.fillFraction;
if (timer.loadNextQuestion)
{
Debug.Log(timer.loadNextQuestion);
if (progressBar.value == progressBar.maxValue)
{
isComplete = true;
return;
}
hasAnsweredEarly = false;
timer.loadNextQuestion = false;
GetNextQuestion();
}
else if (!hasAnsweredEarly && !timer.isAnsweringQuestion)
{
DisplayAnswer(-1);
SetButtonState(false);
}
}
public void OnAnswerSelected(int index)
{
Debug.Log("on answer select");
hasAnsweredEarly = true;
DisplayAnswer(index);
SetButtonState(false);
timer.CancelTimer();
scoreText.text = "Score: " + scoreKeeper.CalculateScore() + "%";
}
void DisplayAnswer(int index)
{
Debug.Log("display answer");
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<Image>();
buttonImage.sprite = correctAnswerSprite;
}
}
void GetNextQuestion()
{
Debug.Log("GET NEXT QUESTION");
Debug.Log(questions.Count);
if (questions.Count > 0)
{
SetButtonState(true);
SetDefaultButtonSprites();
GetRandomQuestion();
DisplayQuestion();
progressBar.value++;
scoreKeeper.IncrementQuestionsSeen();
}
}
void GetRandomQuestion()
{
Debug.Log("GET RANDOM QUESTION");
int index = Random.Range(0, questions.Count);
currentQuestion = questions[index];
if (questions.Contains(currentQuestion))
{
questions.Remove(currentQuestion);
}
}
void DisplayQuestion()
{
Debug.Log("display Question");
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)
{
Debug.Log("set button states");
for (int i = 0; i < answerButtons.Length; i++)
{
Button button = answerButtons[i].GetComponent<Button>();
button.interactable = state;
}
}
void SetDefaultButtonSprites()
{
Debug.Log("set default button sprites");
for (int i = 0; i < answerButtons.Length; i++)
{
Image buttonImage = answerButtons[i].GetComponent<Image>();
buttonImage.sprite = defaultAnswerSprite;
}
}
}
//this is timer.cs;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
[SerializeField] float timeToCompleteQuestion = 30f;
[SerializeField] float timeToShowCorrectAnswer = 10f;
public bool loadNextQuestion;
public float fillFraction;
public bool isAnsweringQuestion;
float timerValue;
void Update()
{
UpdateTimer();
}
public void CancelTimer()
{
timerValue = 0;
}
void UpdateTimer()
{
timerValue -= Time.deltaTime;
if (isAnsweringQuestion)
{
if (timerValue > 0)
{
fillFraction = timerValue / timeToCompleteQuestion;
}
else
{
isAnsweringQuestion = false;
timerValue = timeToShowCorrectAnswer;
}
}
else
{
if (timerValue > 0)
{
fillFraction = timerValue / timeToShowCorrectAnswer;
}
else
{
isAnsweringQuestion = true;
timerValue = timeToCompleteQuestion;
loadNextQuestion = true;
}
}
}
}
hi Nina ,
I think I figured out the issue , and solved it not sure if that was causing the bug ,in the hierarchy on timer game object loadNextQuestion Boolean was enabled, initially once i disabled it ,the issue got resolved,
i have this doubt in the code the Boolean is just declared so, irrespective of editor the default value should be false right or am i understanding it wrong,
Good job on using Debug.Logs to analyse the problem, and on solving the problem!
If loadNextQuestion
is true, the if-block in Update() of the Quiz object gets called. The question is: What happens if this Update() method gets called before the Update() method of the Timer object? The execution order of Unity methods of the same name is random. It might be that fillFraction
has not been calculated yet when the Update() method of the Quiz object gets executed for the first time.
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.