i'm very new to programming and i have a feeling that there is a very stupid mistake here. But can anyone explain me, why instead of 4 messages with a delay of 2 seconds between, i instantaniously get the last message shown only.
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using UnityEngine.UI;
public class Wait : MonoBehaviour {
private int i = 0;
public string[] message;
[SerializeField]
private Text toText;
public IEnumerator Message(float waitTime)
{
toText.text = message[i];
i++;
yield return new WaitForSeconds(waitTime = 2f);
}
void Start()
{
StartCoroutine(Message(i));
StartCoroutine(Message(i));
StartCoroutine(Message(i));
StartCoroutine(Message(i));
}
}
void Start()
{
StartCoroutine(Message(i));
StartCoroutine(Message(i));
StartCoroutine(Message(i));
StartCoroutine(Message(i));
}
I don't think that is doing what you think it should. This will not wait for each StartCoroutine
to finish and will call the next StartCoroutine
.
This is what happens:
The first StartCoroutine(Message(i));
call will start the Message
function.
Once it meets the yield return new WaitForSeconds(waitTime = 2f);
line of code, it will then jump back into the Start()
function.
The next StartCoroutine(Message(i));
will be called then the-same thing will happen again.
When calling a coroutine function from a non coroutine function, as long as you have yield return new WaitForSeconds
, yield return null;
, or yield return
what-ever YieldInstruction
is implemented, the execution will return to that non coroutine function in-which the StartCoroutine
function was called from and continue to execute other code.
To make coroutine wait for another one to finish, make the StartCoroutine(Message(i));
function call from another coroutine function. This will allow you to yield
each coroutine function call. This is called chaining coroutine.
To chain or yield
a coroutine function call, simply put yield return
in front of the StartCoroutine
function. yield return StartCoroutine(Message(i));
public class Wait : MonoBehaviour {
private int i = 0;
public string[] message;
[SerializeField]
private Text toText;
public IEnumerator Message(float waitTime)
{
// toText.text = message[i];
i++;
yield return new WaitForSeconds(waitTime = 2f);
}
void Start()
{
StartCoroutine(startMessage());
}
IEnumerator startMessage()
{
yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns
yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns
yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns
yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns
}
}
Now, each StartCoroutine(Message(i));
call will wait until the first one finishes. You can always use a boolean
variable to do this but it is much better to yield
the StartCoroutine
call.