- Home /
Check how long a bool has been true
Hi,
I saw other threads on this but still couldn't get it to work. I want something to happen after my bool has been true for 5 seconds. I found this piece of code but it doesn't work:
float boolTime = 0;
private bool _switch = false;
public bool switch {
get {
return switch;
}
set {
_switch = value;
if(_switch == true) {
boolTime = Time.time;
}
}
}
void Update() {
if(_switch && (Time.time - boolTime) > 5f) {
print("Success");
}
}
Any tips on how to make this work? Thanks a lot!
Answer by Stratosome · Jul 23, 2018 at 02:35 PM
Hi there!
I get what your code there is supposed to be doing. Personally, I'd just make little timers with coroutines. That way you wouldn't have to clutter your Update with little bool timers or whatever and they could just run on their own. BUT, I think the issue with your code is that you can't have the one thing called "switch". That's a reserved word, so trying to use it for your variable like thing there is causing issues. If you name it to anything else, it should work. Works for me! Although if that's not the issue, let me know and I'll give it another go hah.
Answer by JVene · Jul 23, 2018 at 06:23 PM
When you're writing in an object oriented language like C#, part of the technique is to recognize when an object (a class) is hinting its existence, but isn't yet there. This is one of those occasions, and an opportunity to expand into thinking in terms of objects to handle jobs like this.
The hint comes from the observation that you have a property named switch (which is a keyword you can't use, Google C# switch for examples), and the related boolTime that manages it.
Combined, these two hint at the object that should exist. In C#, structs can be used for small, self contained objects just like classes, so you could use either in this situation. Create the type with something like:
struct TimedBool
{
private bool state;
private float timeLastSet;
public bool IsTrueDelayed( float d )
{
if ( ( Time.time - timeLastSet ) > d ) return state;
return false;
}
public bool Set( bool s )
{
state = s;
timeLastSet = Time.time;
}
}
This is an illustrative psuedo code (that would probably work), but you can flesh this out as you prefer. You could, for example, make state a property as you did in your post. You could consider conversion operators for convenience. The point is you can only set 'state' by going through code which stamps the time. Later, you check for state with something like:
private TimedBool theTimedSwitch = new TimedBool();
void SomeTriggerFunction()
{
theTimedSwitch.Set( true );
}
void Update()
{
if ( theTimedSwitch.IsTrueDelayed( 5f ) ) { ...stuff to do when true after 5 seconds....}
}
Notice this did not bother to check about setting the delay only if setting the bool to true. In your code, you've elected not to set the time when the bool is set to false, but this isn't necessary. Logically, if false is the state, the delay doesn't even matter at all. So, just set the time stamp on all changes to state, it doesn't impact the outcome.
Now you can use a timed bool in any circumstance, have many of them, and not clutter code with multiple related, synchronized tests. The class (or struct) TimedBool synchronizes these two ideas into a single concept. That's what objects are for.
Your answer
![](https://koobas.hobune.stream/wayback/20220612171339im_/https://answers.unity.com/themes/thub/images/avi.jpg)