- Home /
Yield and WaitForSeconds not stopping at correct points?
Hi,
I have a shader with an emission that I am trying to get to pulse stronger and weaker, and have thus a pow with a strength exposed in the shader material. The script is like this:
public class Pulse : MonoBehaviour { private float pulse; public float scale = 0.1f; public bool run = false;
// Use this for initialization void Start () { pulse = renderer.material.GetFloat("_Strength"); }
void Update() { if(run) { if (pulse < 0.5f || pulse > 2.0f) { scale *= -1.0f; }
// Set Scale, which is how much the pulse will increase and decrease
pulse += scale;
// Feed the float of pulse into the _Strength variable in the material/shader
renderer.material.SetFloat("_Strength", pulse);
if (pulse < 0.5f || pulse > 2.0f)
{
print(pulse); run = false;
}
}
else
StartCoroutine(check());
}
IEnumerator check() { print("Yield before, pulse: " + pulse + ", Scale: " + scale); yield return new WaitForSeconds(2.0f); print("Yield after, pulse: " + pulse + ", Scale: " + scale); run = true; }
The pulse is ment to go between a strength of 0.5 and 2, where it should stop at either extremes for a few seconds, before going to the other extreme. Our problem is that it currently stops at one extreme, 0.5, then goes up to 2 but goes down to 0.5 again without waiting, then waits at 0.5 again.. so it is only stopping at one extreme. Any idea as to why? What am I not seeing T_T
Answer by Jean-Fabre · Apr 13, 2011 at 11:15 AM
Hi,
Simply put StartCoroutine(check()); in the same block as when you set run to false and that works.
The full script is below. You'll notice one change, I use a frame based independant animation
pulse += Time.deltaTime*scale;
It's very likely that this is how you actually want this to behave, that is pulse at the same speed regardless of the power of the computer you are running the application in. you simply need to adjust the scale value to accomodate the speed you actually want.
using UnityEngine; using System.Collections;
public class Pulse : MonoBehaviour { public float pulse; public float scale = 0.1f; public bool run = true;
// Use this for initialization
void Start () {
pulse = 1;//renderer.material.GetFloat("_Strength");
}
void Update()
{
if(run)
{
if (pulse < 0.5f || pulse > 2.0f)
{
scale *= -1.0f;
}
// Set Scale, which is how much the pulse will increase and decrease
pulse += Time.deltaTime*scale; // use this for frame independant animation.
// Feed the float of pulse into the _Strength variable in the material/shader
//renderer.material.SetFloat("_Strength", pulse);
if (pulse < 0.5f || pulse > 2.0f)
{
// print(pulse);
run = false;
StartCoroutine(check());
}
}
}
IEnumerator check()
{
print("Yield before, pulse: " + pulse + ", Scale: " + scale);
yield return new WaitForSeconds(2.0f);
print("Yield after, pulse: " + pulse + ", Scale: " + scale);
run = true;
}
}
Bye,
Jean
Thanks for catching the Time.deltaTime, totally forgot about that xD The yield works, but it sometimes got caught in an endless loop as the pulse was always either over 2.0f or below 0.5f and it couldn't get back to a number between 0.5f and 2.0f.
Fixed it by resetting pulse to either 0.51f or 1.99f after the pause (depending on where it was), and it works like a charm now :D
Thanks for the answer :)
Your answer
Follow this Question
Related Questions
C# WaitForSeconds doesn't seem to work ?? 2 Answers
Scrolling Text StartCoroutine not working C# 2 Answers
WaitForSeconds problem with Unity Pro 3 Answers
Fire rate for gun script, c# (not u/s) 1 Answer
Another question about yield, WaitForSeconds in c# 2 Answers