What am I doing wrong? - Timer Hookup issue

Effectively here is what happens, with the code presented as it is at the end of “Simple Timer” and then hooked up like it is in “Connecting the Timer” at the point where he demonstrates it, I noticed something.

TimerValue is never set. It isn’t given a default value. So when the first UpdateTimer method runs, and I proved this via Debug, I got 1 moment of my TimerValue hitting the isAnsweringQuestion but it jumped down into the else of being < 0

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;
    
    bool isAnsweringQuestion = true;
    float timerValue;

    void Start()
    {
        timerValue = timeToCompleteQuestion;
    }


    void Update()
    {
        UpdateTimer();
    }

    public void CancelTimer()
    {
        timerValue = 0f;
    }


    void UpdateTimer()
    {
        timerValue -= Time.deltaTime;
        if(isAnsweringQuestion)
        {
            if(timerValue > 0f)
            { // if answering question and timer is greater than 0
                fillFraction = timerValue / timeToCompleteQuestion;
            }
            else
            {
                timerValue = timeToShowCorrectAnswer;
                isAnsweringQuestion = false;
            }
        }
        else 
        {
            if(timerValue > 0f)
            { // if not answering question and timer is greater than 0
                fillFraction = timerValue / timeToShowCorrectAnswer;
            }
            else
            {
                isAnsweringQuestion = true;
                timerValue = timeToCompleteQuestion;
                loadNextQuestion = true;
            }

        }

    }


}

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] QuestionSO question;

    [Header("Answers")] 
    [SerializeField] GameObject[] answerButtons;
    int correctAnswerIndex;

    [Header("Button Colors")]
    [SerializeField] Sprite defaultAnswerSprite;
    [SerializeField] Sprite correctAnswerSprite;

    [Header("Timer")]
    [SerializeField] Image timerImage;
    Timer timer;

    void Start()
    {
        timer = FindObjectOfType<Timer>();
        DisplayQuestion();
    }

    void Update() 
    {
        UpdateTimer();
        if(timer.loadNextQuestion)
        {
            GetNextQuestion();
            timer.loadNextQuestion = false;
        }
    }

    void UpdateTimer()
    {
        timerImage.fillAmount= timer.fillFraction;
    }


    void DisplayQuestion()
    {
        questionText.text = question.GetQuestion();
        
        for(int index =0 ; index<answerButtons.Length;  index++)
        {
            TextMeshProUGUI buttonText = answerButtons[index].GetComponentInChildren<TextMeshProUGUI>();
            buttonText.text = question.GetAnswer(index);
        }
    }
    
    void GetNextQuestion() //untested feature
    {
        SetButtonState(true);
        SetDefaultButtonSprites();
        DisplayQuestion();
    }

    void SetDefaultButtonSprites()
    {
        for(int index = 0; index < answerButtons.Length; index++)
        {
            Image buttonImage = answerButtons[index].GetComponent<Image>();
            buttonImage.sprite = defaultAnswerSprite;
        }
    }

    public void OnAsnwerSelected(int index) 
    {
        Image buttonImage;
        if(index == question.GetCorrectAnswerIndex())
        {
            questionText.text = "Correct!";
            buttonImage = answerButtons[index].GetComponent<Image>();
            buttonImage.sprite = correctAnswerSprite;
        }
        else
        {
            int correctIndex = question.GetCorrectAnswerIndex();
            string correctText = question.GetAnswer(correctIndex);
            questionText.text = "Sorry the correct answer was; \n" + correctText;
            buttonImage = answerButtons[correctIndex].GetComponent<Image>();
            buttonImage.sprite = correctAnswerSprite;
        }
        SetButtonState(false);
        timer.CancelTimer();
    }


    void SetButtonState(bool state)
    {
        for(int i = 0; i < answerButtons.Length; i++)
        {
            Button button = answerButtons[i].GetComponent<Button>();
            button.interactable = state;
        }
    }





}

Note, I did as a work around, first set my Timer in a Start Method.

So basically, following the code from the lecture (Code that is here) you can follow along.

Following the code as I understand it…

As I was typing this I found my problem. I wanted to share this as I think this is technically a bug how it’s working.

So bottom line is I did a KDIFF and the most signifcant differnce is the ``` public bool isAnsweringQuestion;


I default mine to true, in the lesson it is not. This means it technically goes into the LoadNextQuestionState almost immediately.... I am sure this will be found in a later lecture... but for now.... just wanted to note this as it drove me crazy.
1 Like

Thanks for sharing your solution! It’s great to see that you analysed this problem further.

Gary’s project is not complete yet. An important detail is still missing, so please keep watching. :slight_smile:

As I continued going through the course I see what it ended up being utilized for. We begin with no question so “next question” gives us the first question in the beginning. We fall into False False So that makes sense.

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

Privacy & Terms