- Home /
Turn bool on/off x time every few seconds in coroutine
So I feel really stupid about this problem, I'm sure I'm missing something small.
I'm basically trying to turn a boolean on and off x amount of time at a specific interval. I'm using a coroutine for that, which has 3 passed variable:
blinkCount
blinkSpeed
renderer
What I need to do is:
switch boolean flag for each blinkCount every x seconds. Here's what I have so far:
using UnityEngine;
using System.Collections;
public class BlinkObject : MonoBehaviour
{
private static bool blinkOn = false;
public static IEnumerator BlinkMultipleObjects(int blinkCount, float blinkSpeed, Renderer objRenderer) {
while( blinkCount > 0 )
{
blinkCount--;
yield return new WaitForSeconds(1f);
blinkOn = !blinkOn;
// Turn the object's renderer on and off.
objRenderer.enabled = blinkOn;
yield return null;
}
}
}
The code above keeps turning the blinkOn flag on and off on every frame, instead of every 1 second. I know I'm doing it wrong, I just don't know how to make it work the way I want!
Thanks in advance!
Answer by Eric5h5 · Jul 11, 2011 at 06:23 AM
The main problem is that you're using "static"--remove that, since it prevents the coroutine from working. Coroutines shouldn't be static, since they can have any number of instances. Some other things: you can toggle the renderer itself, so you don't need the blinkOn variable (which should be local to the coroutine anyway, not global). You're not using the blinkSpeed variable; presumably that should be used in WaitForSeconds. The "yield return null" at the end isn't necessary since you're using WaitForSeconds anyway. Kind of trivial, but "BlinkMultipleObjects" isn't an accurate name, since only one object is being affected.
using UnityEngine;
using System.Collections;
public class BlinkObject : MonoBehaviour
{
public IEnumerator ToggleRenderer (int blinkCount, float blinkSpeed, Renderer objRenderer) {
while( blinkCount-- > 0 )
{
yield return new WaitForSeconds(blinkSpeed);
objRenderer.enabled = !objRenderer.enabled;
}
}
}
Eric5h5, thanks for your help...I knew I was over-complicating things a lot hahaha. One quick question, why does a static variable prevent a Coroutine from running correctly?
Static means one instance, and coroutines can have any number of instances.
But can you force a coroutine to only have 1 instance, or is that just stupid? For example, I have a few static coroutines, one starts the raceStart timer and will always be only 1 instance no matter what. Is that like bad practice or is it really a big no-no?
Thanks for your time Eric5h5, I really appreciate the help!
Answer by Chrisg · Jul 11, 2011 at 04:26 AM
Frames happen at different speeds on every computer, based on cpu access and speed. You can't use them as measuring sticks. Instead, you use the time between each frame, and add it together to get seconds/minutes, etc. This is accessed via Time.deltaTime. I use JS, not c# so I'm not sure on the exact implementation, but something like
float delay = 5; //pause between toggles
float ticks = 0.0; //time since last toggle
bool toggle = true; //toggle var
function(delay, ticks, toggle)
{
if(ticks >= delay)
{
toggle != toggle;
ticks = 0;
}
else
ticks += Time.deltaTime;
}
should direct you toward the c# answer(I don't imagine it's far different).
ronronmx's code isn't using frames (at least that's the intention), it's a coroutine using WaitForSeconds. You don't need to use Time.deltaTime for anything here.