Edit: Please disregard this post. I found out there was a trivial answer: another part of my code was modifying the cooldown timer and after I got rid of it this started working correctly.
I have a C# script where the player can spawn fighters and there’s a cooldown timer between spawnings. After a spawn, the game shows a cooldown timer bar and I’m trying to make the bar start full, decrease, and ultimately disappear (using .SetActive(false)) when it reaches zero and you can spawn another fighter. In Update() I have an if() that sees if the cooldown is greater than zero; if so then it decrements the cooldown and then an inner if() checks if it fell to zero or less, and if it fell to zero or less then it deactivates the timer bar.
When I do that, everything seems to work except when the cooldown finally reaches zero or less the script doesn’t always deactivate the cooldown bar. Sometimes it does, and sometimes it doesn’t, which seems weird.
Even after a spawning when the cooldown bar doesn’t disappear, in the inspector I can see that the cooldown value has indeed dropped below zero and I’m able to spawn fighters again (the spawning code checks to make sure the cooldown is zero or less). I tried putting a Debug.Log within the final if() that checks to see if the cooldown reached zero or less, and the Debug.Log only gives a message if the cooldown bar does disappear. On spawnings when the cooldown bar doesn’t disappear, Debug.Log isn’t giving any message, so it looks like the problem is that the inner if() isn’t triggering even though it should. For the purposes of making my game, I could find another workaround like using an Invoke() to hide the cooldown bar while still letting Update() handle decreasing its size, but I get the feeling there’s something fundamental I’m not understanding about how C# and/or Update() and/or Unity is working that is making this approach so unreliable and I’d like to understand why it’s unreliable and if it has any implications on how to avoid similar pitfalls.
Here’s the code, the first block is what’s inside Update() and the others are methods that it calls:
// If spawning is in cooldown, decrement the cooldown timer
// When it reaches zero, hide the cooldown bar
if (cooldown > 0f) {
cooldown -= Time.deltaTime;
SetCooldownBar();
if (cooldown <= 0f) {
Debug.Log("Attempting to hide cooldown bar");
ShowCooldownBar(false);
}
// } else {
// ShowCooldownBar(false);
}
void SetCooldownBar() {
Vector3 cooldownBarScale = cooldownBarMax.transform.localScale;
cooldownBarScale.x *= cooldown / cooldownMax;
cooldownBar.transform.localScale = cooldownBarScale;
}
void ShowCooldownBar(bool onoff) {
cooldownBar.SetActive(onoff);
cooldownBarMax.SetActive(onoff);
}
I’ve tried changing the inner if() from “if (cooldown <= 0f)” to “if (!(cooldown > 0f))” and that doesn’t help.
I initially had the call to SetCooldownBar() within an else after the inner if() instead of happening right before the inner if(), and I still had the same problem of unreliable triggering of the inner if().
If I un-comment the else near the end of the block within Update() then the cooldown bar always disappears, but calling a function to hide the cooldown bar on every Update seems pretty wasteful (or at least it would make me look like an idjit of a programmer).