keycode and && statment not working?

cant work out why this isn’t working it makes sense to me if button pressed and special bar is above 100 then I can activate and special goes to 0
well that works my special drops to 0 and will only drop to 0 when my special is == 100 the problem is as soon as game starts its like my special is always activated regardless of my if statement

void LateUpdate ()
{
	if (Input.GetKeyDown (KeyCode.Q) && currentSpecial == 100)
		currentSpecial = minSpecial;

	colliders = Physics.OverlapSphere (transform.position, radius);


	foreach (Collider col in colliders) {
		if (col.tag == "Enemy")
			Destroy (col.gameObject);
		else if (col.tag == ("Bullet"))
			Destroy (col.gameObject);
	}
	currentMana = Mathf.Clamp (currentMana, minMana, maxMana);
	if (currentSpecial > maxSpecial)
		currentSpecial = maxSpecial;
	if (currentSpecial < minSpecial)
		currentSpecial = minSpecial;
	UpdateSpecialbar ();
}

}

Well, first of all your if statement at the top only affects the line / statement that comes directly after it. So in your case the only conditional code is this line:

currentSpecial = minSpecial;

That means your OverlapSphere call as well as your foreach loop are executed unconditionally every frame. I guess that’s your actual “special” code.

This is actually true for any control flow statements (if, for, while, …) they only affect the one statement that is follwing. However you can “group” several statements into one block by using curly brackets. You already did this with your foreach loop.

However it’s not clear when exactly your “special” should be active. At the moment we can’t see where “currentSpecial” is actually increased / decreased.

If you want the effect to only occure “once” when the button is pressed you should simply include your foreach loop and the OverlapSphere in the if body

if (Input.GetKeyDown (KeyCode.Q) && currentSpecial == 100)
{
    currentSpecial = minSpecial;
    colliders = Physics.OverlapSphere (transform.position, radius);
 
    foreach (Collider col in colliders)
    {
        if (col.tag == "Enemy")
            Destroy (col.gameObject);
        else if (col.tag == ("Bullet"))
            Destroy (col.gameObject);
    }
}

However if you want to just “activate” the special and let it last for a few sec you would need some sort of variable to remember the “active” state. You would use that variable to selectively enable / disable the OverlapSphere and foreach loop code. When you press the button to acivate it you would set the active variable to true. When the time ran out you set it back to false.

Note that if currentSpecial is a float value you shouldn’t compare it to equality with 100. If you dynamically increase or decrease the value it’s unlikely that you ever hit the exact value. If “maxSpecial” is actually 100, then you shouldn’t use the magic number “100” in your if statement. Compare it to “maxSpecial” instead.

In general if you compare float values it’s better to check a range like

if ( currentSpecial >= maxSpecial )

This statement is true when currentSpecial is equal or greater than maxSpecial.

It’s difficult to actually follow your logic and code as important parts are missing. At the same time the clamping of your “currentMana” value seems misplaced as that value isn’t changed in LateUpdate.

It’s always better to clamp a value when it’s actually changed. This is usually done by providing a set method (either a seperate method or using a property)

void SetMana(float aNewValue)
{
    currentMana = Mathf.Clamp (aNewValue, minMana, maxMana);
}

So when you want to change the value somewhere you would do

SetMana(currentMana + 5 * Time.deltaTime);

This would increase the value by 5 every second. This ensures at no point in time currentMana can be larger than maxMana or smaller than minMana.

Or as a property:

public float CurrentMana
{
   get { return currentMana; }
   set { currentMana = Mathf.Clamp (value, minMana, maxMana);}
}

And change it like this:

CurrentMana += 5 * Time.deltaTime;

This would do the same