I am making a game where I want an overlay to appear for a specified amount of seconds before disappearing. I am using a Coroutine to do this, but it is now working. Is there a way to fix this issue or should I do it another way. I don't get any errors, but the coverObject
doesn't display for 3 seconds and hide for 2 seconds as specified in the code.
The code:
void playRound()
{
coverObject.gameObject.SetActive(true);
for (int i = 0; i < keys - 1; i++)
{
GameObject instantiated = Instantiate(key);
}
waitSecs(3);
coverObject.gameObject.SetActive(true);
GameObject instantiatedCorrect = Instantiate(key);
correctKey = instantiatedCorrect;
waitSecs(2);
coverObject.gameObject.SetActive(false);
}
void waitSecs(int seconds)
{
StartCoroutine(WaitSecsCoroutine(seconds));
}
IEnumerator WaitSecsCoroutine(int seconds)
{
yield return new WaitForSeconds(seconds);
}
your method playRound
will keep running while the WaitSecsCoroutine
coroutine is yielding. This is because control is returned to the calling method as soon as a yield return
statement is reached.
The following is happening:
playRound
is calledwaitSecs
is calledwaitSecs
calls to coroutine waitSecsCoroutine
waitSecsCoroutine
reaches the yield return new WaitForSeconds()
waitSecs
, which in turn returns to PlayRound
playRound
continues with coverObject.gameObject.SetActive(true);
and the subsequent code while waitSecsCoroutine
is still waiting.What you need to do is make playRound
a coroutine as well, and use yield return WaitSecsCoroutine
so the function halts its execution until WaitSecsCoroutine
is finished:
IEnumerator playRound()
{
coverObject.gameObject.SetActive(true);
for (int i = 0; i < keys - 1; i++)
{
GameObject instantiated = Instantiate(key);
}
yield return WaitSecsCoroutine(3);//This now waits until WaitSecsCoroutine is finished
coverObject.gameObject.SetActive(true);
GameObject instantiatedCorrect = Instantiate(key);
correctKey = instantiatedCorrect;
yield return WaitSecsCoroutine(2);
coverObject.gameObject.SetActive(false);
}
Note however that you can also just call the WaitForSeconds
directly from your playRoudn
method too once it is a coroutine, without needing a seperate function
IEnumerator playRound()
{
coverObject.gameObject.SetActive(true);
for (int i = 0; i < keys - 1; i++)
{
GameObject instantiated = Instantiate(key);
}
yield return new WaitForSeconds(3);
coverObject.gameObject.SetActive(true);
GameObject instantiatedCorrect = Instantiate(key);
correctKey = instantiatedCorrect;
yield return new WaitForSeconds(2);
coverObject.gameObject.SetActive(false);
}
Alternatively you could move the code you want to execute after the wait into your WaitSecsCoroutine
method.