How to add multiple yield return new wait for seconds inside an IEnumerator?
Hello
I'm working in a little app in Unity using UI, and I want to learn/know how to use the IEnumerator to stack multiple yield.
My goal is to use coroutines to disable UI elements after a short time pressing a button
This is my code so far:
using System.Collections;
using UnityEngine;
public class Script_EnableDisableGo : MonoBehaviour
{
[Header("BackGround canvas")]
public GameObject disableBg;
[Header("ForeGround canvas")]
public GameObject disableFg;
[Header("Wait before disable")]
public float timeToWait;
public void DisableBackGroundCanvas()
{
StartCoroutine(Wait());
}
public void DisableForeGroundCanvas()
{
StartCoroutine(Wait());
}
IEnumerator Wait()
{
yield return new WaitForSeconds(timeToWait);
disableBg.SetActive(false);
yield return new WaitForSeconds(timeToWait);
disableFg.SetActive(false);
}
}
Main behaviour:
After pressing a button, a UI element shows and the previous get disabled, and after pressing another button the disabled UI element shows enabled
Main UI window is visible (press button) [wait for 1 sec] -> New UI window is visible | Main UI window is disabled
New UI window is visible (press return button)[wait for 1 sec] -> Main UI window is visible | New Ui window is disabled
When I run this coroutine, those elements are disabled at the same time, and I just want to disable one at a time
What am I doing wrong?
Help and feedback are very appreciated
Can't see anything wrong with the coroutine.
You talk of enabling and disabling 2 different objects but in this sample there is just 1 method to make 1 transition. Are you reassigning disableFg
and disableBg
somewhere to control what gets hidden and what shown?
Do you have 2 buttons with this samw script or what is the setup?
Answer by TBruce · Aug 12, 2016 at 05:59 PM
From your code and your explanation of what you are attempting to do this is what I currently understand (correct me if I get anything wrong)
You have 2 windows named MainWindow (activated) and NewWindow (deactivated).
You have 2 buttons "Hide MainWindow Button" (enabled) and "Hide NewWindow Button" (disabled)
When you press the MainWindow button you want to
Disable MainWindow button (where this is done is not defined)
Enable NewWindow button (where this is done is not defined)
Deactivate the MainWindow
wait one second
Activate the NewWindow
wait one second
4. When you press the NewWindow button you want to
Disable NewWindow button (where this is done is not defined)
Enable MainWindow button (where this is done is not defined)
Deactivate the NewWindow
wait one second
Activate the MainWindow
wait one second
Then it seems that all you need to do is this
using System.Collections;
using UnityEngine;
public class Script_EnableDisableGo : MonoBehaviour
{
[Header("BackGround canvas")]
public GameObject backGroundCanvas; // main window???
[Header("ForeGround canvas")]
public GameObject foreGroundCanvas; // new window???
[Header("Wait before disable")]
public float timeToWait;
public void DisableBackGroundCanvas()
{
StopCoroutine("Wait");
StartCoroutine(Wait(backGroundCanvas, foreGroundCanvas));
}
public void DisableForeGroundCanvas()
{
StopCoroutine("Wait");
StartCoroutine(Wait(foreGroundCanvas, backGroundCanvas));
}
IEnumerator Wait(GameObject go1, GameObject go2)
{
yield return new WaitForSeconds(timeToWait);
go1.SetActive(false);
yield return new WaitForSeconds(timeToWait);
go2.SetActive(true);
}
}
Or instead of having two functions (DisableBackGroundCanvas/DisableForeGroundCanvas) you can do everything in one function like this (this also toggles the buttons)
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class Script_EnableDisableGo : MonoBehaviour
{
[Header("BackGround canvas")]
public GameObject backGroundCanvas;
[Header("ForeGround canvas")]
public GameObject foreGroundCanvas;
[Header("Main Window Button")]
public Button MainWindowButton; // rename this to your liking
[Header("New Window Button")]
public Button NewWindowButton; // rename this to your liking
[Header("Wait before disable")]
public float timeToWait;
public void DisableEnableWindows() // rename this to your liking
{
if ((MainWindowButton != null) && (NewWindowButton != null))
{
MainWindowButton.enabled = !MainWindowButton.enabled;
NewWindowButton.enabled = !NewWindowButton.enabled;
}
StopCoroutine("Wait");
if (backGroundCanvas.activeSelf)
StartCoroutine(Wait(backGroundCanvas, foreGroundCanvas));
else
StartCoroutine(Wait(foreGroundCanvas, backGroundCanvas));
}
IEnumerator Wait(GameObject go1, GameObject go2)
{
yield return new WaitForSeconds(timeToWait);
go1.SetActive(false);
yield return new WaitForSeconds(timeToWait);
go2.SetActive(true);
}
}
Awesome!!
Very good answer!!
Sorry, I didn't write more details...
Here are more details:
I have 2 canvas
1 is for $$anonymous$$ain window, 1 is for New window
$$anonymous$$ain window's canvas is enabled with all its UI elements, New window's canvas is disabled with all its UI elements
Button from $$anonymous$$ain window calls New window enabling its root canvas and then disabling after 1 sec $$anonymous$$ain window's root canvas
Return button from New window calls $$anonymous$$ain window enabling its root canvas and then disabling after 1 sec New window's root canvas
So on and so forth...
Thanks for the answer and I'll check the code
Your answer
Follow this Question
Related Questions
How to skip WaitForSeconds? 1 Answer
Could not load source 'Coroutines.cs': No source available. 1 Answer
Scene Change after some time when achieving a certain Score C# 1 Answer
Unity WaitForSeconds Not Working Inside Update or a Loop 2 Answers
Trying to add a delay to an Instantiate in a For Loop 0 Answers