Before anything, first I’d just like to share the code that the instructor guided us through in this lecture:
public class Timer : MonoBehaviour
{
[SerializeField] float timeToAnswerQuestion = 30f;
[SerializeField] float timeToShowCorrectAnswer = 10f;
bool isAnsweringQuestion;
float timerValue;
public float fillFraction;
public bool displayNewQuestion;
void Update()
{
UpdateTimer();
}
public void CancelTimer()
{
timerValue = 0;
}
void UpdateTimer()
{
timerValue -= Time.deltaTime;
if (isAnsweringQuestion)
{
{
fillFraction = timerValue/timeToAnswerQuestion;
}
else
{
timerValue = timeToShowCorrectAnswer;
isAnsweringQuestion = false;
}
}
else
{
if (timerValue > 0)
{
fillFraction = timerValue/timeToShowCorrectAnswer;
}
else
{
timerValue = timeToAnswerQuestion;
isAnsweringQuestion = true;
displayNewQuestion = true;
}
}
}
}
One thing that I was confused about in the above code was the variable “timerValue” because although the variable wasn’t assigned a value, the instructor was still subtracting Time.DeltaTime from it.
And when you run the code (after doing the first challenge from the next lecture), there was no error. So this confused me as to how the code was actually working. Thus, in a proper programmer fashion, I filled the code with Log statements. This is the updated code [It’ll be helpful to look at when I show the results]:
public class Timer : MonoBehaviour
{
[SerializeField] float timeToAnswerQuestion = 30f;
[SerializeField] float timeToShowCorrectAnswer = 10f;
bool isAnsweringQuestion;
float timerValue;
public float fillFraction;
public bool displayNewQuestion;
void Update()
{
Debug.Log("Initial timer Value: " + timerValue);
Debug.Log("The state of isAnsweringQuestion at the start: " + isAnsweringQuestion);
UpdateTimer();
}
public void CancelTimer()
{
timerValue = 0;
}
void UpdateTimer()
{
timerValue -= Time.deltaTime;
Debug.Log("Timer Value when first subtracted: " + timerValue);
if (isAnsweringQuestion)
{
Debug.Log("The Player is Answering Question");
if (timerValue > 0)
{
Debug.Log("The Player is Answering the Question & timer > 0");
fillFraction = timerValue/timeToAnswerQuestion;
}
else
{
Debug.Log("The Player is Answering the Question & timer < 0");
timerValue = timeToShowCorrectAnswer;
isAnsweringQuestion = false;
}
}
else
{
Debug.Log("The Player is Checking the Correct Answer");
if (timerValue > 0)
{
Debug.Log("The Player is Checking the Correct Answer & timer > 0");
fillFraction = timerValue/timeToShowCorrectAnswer;
}
else
{
Debug.Log("The Player is Checking the Correct Answer & timer < 0");
timerValue = timeToAnswerQuestion;
isAnsweringQuestion = true;
displayNewQuestion = true;
Debug.Log("The new question has been loaded and is being displayed");
}
}
}
}
As you can see, there are a lot of Log statements. But anyways, the purpose of me doing this was to see what happened when the Update Method runs the first ever time. And this was the result:
[Please refer the code directly above the image to see where each debug statement is if there’s any confusion. That’ll sort of show the flow.]
So the way the way the instructor’s guided script works is that, as expected, the timer value is 0. BUT since the player is currently not answering a question, when the script goes into the UpdateTimer() method, the script goes into the first else statement and then the second else statement (since timerValue < 0) - and thus the timerValue is assigned the timeToAnswerQuestion value (the value we want to set).
That’s why, when we run the script here, we don’t notice any issue because the value of the timer is being set after the first update.
But I do find this approach kind of wrong? Because according to this approach, on the first update, the script actually skips the first question screen and loads and displays the next question (since the displayNextQuestion bool is set to true).
So I decided to fix it and here’s the code for that:
public class Timer : MonoBehaviour
{
[SerializeField] float timeToAnswerQuestion = 30f;
[SerializeField] float timeToShowCorrectAnswer = 10f;
bool isAnsweringQuestion = true;
float timerValue;
public float fillFraction;
public bool displayNewQuestion;
//This Start method I have added - not in the lecture video.
void Start()
{
timerValue = timeToAnswerQuestion;
}
void Update()
{
UpdateTimer();
}
public void CancelTimer()
{
timerValue = 0;
}
void UpdateTimer()
{
timerValue -= Time.deltaTime;
if (isAnsweringQuestion)
{
if (timerValue > 0)
{
fillFraction = timerValue/timeToAnswerQuestion;
}
else
{
timerValue = timeToShowCorrectAnswer;
isAnsweringQuestion = false;
}
}
else
{
if (timerValue > 0)
{
fillFraction = timerValue/timeToShowCorrectAnswer;
}
else
{
timerValue = timeToAnswerQuestion;
isAnsweringQuestion = true;
displayNewQuestion = true;
}
}
}
}
I basically initiliazed isAnswerQuestion as true and assigned the timerValue in the start method. This way the script will first go through the first question and not directly move on to the next question.
Just thought I share this observation because I saw a similar question on the Udemy lecture itself but didn’t have a conclusive answer.