- Home /
Updating waitforseconds in IEnumerator
I want to update the waitforseconds in runtime, is this somehow possible without restarting the IEnumerator? Or is there another way to get this to work?
void Update()
{
animationwait = (1 / jpm) * 60;//this is infinity at start so the coroutine stops and decreases later on when increasing jpm
if (jpm > 0 && !CoroutineIsRunning) {StartCoroutine("Animations");}
if(lastanimationwait != animationwait)//to update the coroutine
{
StopCoroutine("Animations");
CoroutineIsRunning = false;
lastanimationwait = animationwait;
StartCoroutine("Animations");
}
}
public IEnumerator Animations()
{
while(true)
{
CoroutineIsRunning = true;
yield return new WaitForSeconds(animationwait);
// change animations later with skills and stuff;
babe.animation["Idle"].speed = 1.0f;
babe.animation.Play ("Idle");
}
}
I hope you can help me with that. Thanks in advance.
Answer by robertbu · Oct 06, 2014 at 12:53 AM
If you are talking after the WaitForSeconds() is complete, then yes it will pickup the new value the next time it loops through. If you want to interrupt or reduce it during the WaitForSeconds, then you could replace your WaitForSeconds code and create another class instance variable called 'waitTime'. Then you could:
waitTime = animationwait;
while (waitTime > 0.0f) {
waitTime -= Time.deltaTime;
yield return null;
}
Then if you change 'waitTime', it will be immediately reflected in the amount of time to wait.
Yes i want to interrupt the WaitforSeconds and change the amount in runtime. After those seconds as you have seen i want to play my animation. When i use your codepiece my animation keeps repeating because waitTime is > 0.0f the whole time.
If i do if(waitime == 0) { babe.animation["Idle"].speed = 1.0f; babe.animation.Play ("Idle"); } in the coroutine it wont play my animation and also stops the coroutine at -0.007163752. Any idea how to fix it?
I need to see your revised code. There is no way that waitTime can remain greater than 0.0 unless Time.timeScale is 0.0 because of this line:
waitTime -= Time.deltaTime;
Note that the above code replaces this line:
yield return new WaitForSeconds(animation wait);
And 'waitTime' needs to be declared at the class level, not within the Animations coroutine. And changing 'waitTime' only effects the current cycle through the while() loop. You also have to change 'animationwait' if you want a different wait in next cycle.
waitTime decreases because of -= Time.deltatime. Time.timescale has nothing to do with it.
I change... animationwait = (1 / jpm) * 60; ...when i buy an item. Items increasing jpm. So animationwait decreases the more items i buy. waitTime = animationwait is setting it to 600 if you buy the first item.
After 600 seconds the animation should play and the timer should begin again. If i update animationwait because i bought another item, it should needs less time until playing the animation.
I hope you know what i mean.
Your code is not what I was suggesting. In your original code, you would replace the single WaitForSeconds() line I specified with the code I specified. You will have nested while() loops.
void Update()
{
animationwait = (1 / jpm) * 60;//this is infinity at start so the coroutine stops and decreases later on when increasing jpm
if (jpm > 0 && !CoroutineIsRunning) {StartCoroutine("Animations");}
if(lastanimationwait != animationwait)//to update the coroutine
{
StopCoroutine("Animations");
CoroutineIsRunning = false;
lastanimationwait = animationwait;
StartCoroutine("Animations");
}
}
public IEnumerator Animations()
{
if (animationwait <= 0.0f) {
Debug.Log ("animationwait need to be greater than 0");
yield break;
}
while(true)
{
CoroutineIsRunning = true;
waitTime = animationwait;
while (waitTime > 0.0f) {
waitTime -= Time.deltaTime;
yield return null;
}
// change animations later with skills and stuff;
babe.animation["Idle"].speed = 1.0f;
babe.animation.Play ("Idle");
}
}
@robertbu:
Note: if animationwait is set to 0 or a negative value your application will crash. Here it would be a good idea to implement a safety check or at least an additional yield return null; inside the outer loop. A crash is the worst what can happen to your application as it will take down the editor as well.