Hello!
I have no idea how to explain this in the title, so I will put the explanation here:
I want to make a piece of code that does something similar to this: when you press the spacebar a red GameObject turns blue. If that GameObject is blue, it goes back to red and so on. This is what I have:
bool TestBool()
{
if(Input.GetKeyDown(KeyCode.Space))
{
if(TestBool() == true)
{
return false;
}
else
{
return true;
}
}
}
However, when I try to add to this code (This code gives me error CS0161) it will give me a StackOverflow. I would like to know a way where this code can work correctly. Thanks.
You’re calling TestBool, but then TestBool calls itself, which calls itself, which calls itself, which calls itself… at least until it doesn’t register that space has been pushed down. Like, I don’t understand what you’re doing there. That would lead to a stackoverflow issue depending on how you changed the code.
If it’s a matter of changing a value, just have a variable that you change. Not calling your own method from your own method like this.
private bool aVariable = false;
bool TestBool()
{
aVariable = !aVariable;
return aVariable;
}
Do your check for Input in Update, and then call TestBool from Update if space is pressed. Now, this is a simple bool switch and because TestBool is private, it might seem odd to change the field variable and return it, but yes, it can be done. Either way, if you want to change a color, you can do the same concept.
private bool isBlue= false;
void ChangeColor()
{
if(isBlue)
//Set color to red, set bool to false
else
//Set color to blue, set bool to true.
}
Again, call ChangeColor from Update when space is pressed. Don’t be afraid to use variables! That is what they are there for. 
There is no way that kind of code can work correctly. TestBool will just call itself ad infinitum as soon as you press Space bar.
Imagine looking a mirror through another mirror. That’s what you did. An error like Stack Overflow prevents you from overfilling a buffer that’s responsible for keeping track of what has been called before.
To do this properly, we introduce a bool variable that lives inside the object, unlike the usual local variables which live in the function itself. This object-wide variables are called “class fields” or “class members”. We’ll use this type of a variable as a switch, which we can flick on or off. The benefit is that it’ll keep its state until the object, as a whole is removed from the memory.
In your case the object is a component with this code, and you probably don’t want to remove it, so it’ll stay put for as long as you’re in the play mode.
using UnityEngine;
public class SpaceBarTest : MonoBehaviour {
private bool _switch; // we denote such variables with _ in front
// we detect keyboard events in Update
public void Update() {
if(Input.GetKeyDown(KeyCode.Space)) {
_switch = !_switch; // here we "toggle" the switch by assigning its negated state
Debug.Log(string.Format("Switch is now {0}.", _switch? "on" : "off"));
}
}
}
Alternative ways to “flick” the boolean variable are just more verbose, with no added value
if(_switch == true) {
_switch = false;
} else {
_switch = true;
}
is just the same as if(_switch) { ... }
because the if
’s condition must evaluate to a boolean value anyways.
And so if all we do is assigning a counter-value (via logical negation which works with boolean values)
if(_switch) {
_switch = !_switch; // here it was true, so it'll become false
} else {
_switch = !_switch; // here it was false, so it'll become true
}
then we could just as well simply do a single _switch = !switch
, and get rid of the if
altogether.
Alternative way to display the result would be
Debug.Log($"Switch is now {(_switch? "on" : "off")}.");
This notation $“” is called string interpolation and is used for quickly formatting debugging messages (or other textual data) such as this one. Learn more about the ternary (or conditional) operator (?:). It is essentially very similar to how if
works, but as an expression (edit: as opposed to statements). Note that here we have to distinguish true
from false
, because the words are different.