Reputation: 1
Hello I've been having trouble with the Coroutine function and wait for seconds. After clicking a button my code should:
However what i get is:
How can I get it so that the wait stops the code carrying on for the time correctly.
IEnumerator wait(){ // This is the function to call it to wait
Debug.Log ("Before Wait");
yield return new WaitForSeconds (2);
Debug.Log ("After Wait");
}
void Update () {
if (chosen == false) {
if (choice != "")
chosen = true;
}
if (chosen == true){
enemyChoice = "";
int n = rnd.Next(num.Count);
enemyChoice = choices [n];
Debug.Log (choice); // Here choice should be printed, then the coroutine started and then enemy choice printed
StartCoroutine (wait ());
Debug.Log (enemyChoice);
chosen = false;
toDecide = true;
}
if (toDecide == true){ // sorry for the clunky way of deciding the result
if (choice == enemyChoice) {
Debug.Log ("Draw");
} else if (choice == "rock" && enemyChoice == "paper") {
Debug.Log ("Lose");
} else if (choice == "rock" && enemyChoice == "scissors") {
Debug.Log ("Win");
} else if (choice == "paper" && enemyChoice == "rock") {
Debug.Log ("Win");
} else if (choice == "paper" && enemyChoice == "scissors") {
Debug.Log ("Lose");
} else if (choice == "scissors" && enemyChoice == "paper") {
Debug.Log ("Win");
} else if (choice == "scissors" && enemyChoice == "rock") {
Debug.Log ("Lose");
} else {
Debug.Log ("Error");
}
toDecide = false;
choice = "";
enemyChoice = "";
}
}
Upvotes: 0
Views: 2538
Reputation: 4105
First you have to understand that Update
is a method that is called every frame. Again and again.
If your game is hitting 60 frames per second, this means that Update
will be called 60 times per second (You can check this adding Debug.Log("Update!");
in Update()
).
Now, if you want to have some logic that waits for x seconds it should be outside Update
, because, as we know Update
will be called again and again, without caring about any WaitForSeconds
.
Here is a simple example of two methods (well, one is a method and another is a coroutine) and the result of the execution:
// Use this for initialization
void Start()
{
Method1();
StartCoroutine(Method2CR());
}
// Update is called once per frame
void Update() {
// I don't want call my methods/Coroutines many times per frame..
}
IEnumerator Wait5Seconds()
{
yield return new WaitForSeconds(5f);
}
void Method1()
{
Debug.Log("Method1 before Wait5Seconds: " + Time.time);
StartCoroutine(Wait5Seconds());
Debug.Log("Method1 after Wait5Seconds: "+ Time.time);
}
IEnumerator Method2CR()
{
Debug.Log("Method2CR before Wait5Seconds: "+ Time.time);
yield return StartCoroutine(Wait5Seconds());
Debug.Log("Method2CR after Wait5Seconds: " + Time.time);
}
and the output is:
Method1 before Wait5Seconds: 0
Method1 after Wait5Seconds: 0
Method2CR before Wait5Seconds: 0
Method2CR after Wait5Seconds: 5.010797
You can read this to get an idea of what is going on behind the scenes on Monobehaviour elements. Look at the Script Lifecycle Flowchart
picture.
Upvotes: 2
Reputation: 7356
Similar questions have been asked many times before, on StackOverflow and on Unity Answers.
Coroutines do not pause the execution of the function they have been called into. You have to put your logic inside a big coroutine instead :
void Start()
{
StartCoroutine( GameLogic() ) ;
}
IEnumerator GameLogic () {
while (true )
{
if (chosen == false) {
if (choice != "")
chosen = true;
}
if (chosen == true){
enemyChoice = "";
int n = rnd.Next(num.Count);
enemyChoice = choices [n];
Debug.Log (choice); // Here choice should be printed, then the coroutine started and then enemy choice printed
Debug.Log ("Before Wait");
yield return new WaitForSeconds (2);
Debug.Log ("After Wait");
Debug.Log (enemyChoice);
chosen = false;
toDecide = true;
}
if (toDecide == true){ // sorry for the clunky way of deciding the result
if (choice == enemyChoice) {
Debug.Log ("Draw");
} else if (choice == "rock" && enemyChoice == "paper") {
Debug.Log ("Lose");
} else if (choice == "rock" && enemyChoice == "scissors") {
Debug.Log ("Win");
} else if (choice == "paper" && enemyChoice == "rock") {
Debug.Log ("Win");
} else if (choice == "paper" && enemyChoice == "scissors") {
Debug.Log ("Lose");
} else if (choice == "scissors" && enemyChoice == "paper") {
Debug.Log ("Win");
} else if (choice == "scissors" && enemyChoice == "rock") {
Debug.Log ("Lose");
} else {
Debug.Log ("Error");
}
toDecide = false;
choice = "";
enemyChoice = "";
}
yield return null ; // To wait one frame
}
}
Upvotes: 1