I am currently making a game similar to Flappy Bird, and I have an if
statement nested inside another if
statement. When the first if
statement becomes false
, the other if
statement still runs, but it only runs once. It should not be running when the first if
statement returns false.
void Update()
{
if(!passed) {
if(Player.position.x >= gameObject.GetComponent<Transform>().position.x) {
Debug.Log("done");
passed = true;
}
}
}
As you can see when it first starts, the passed boolean becomes true
which means it shouldn't run again after completion. However when I pass the obstacle for the first time in-game, it prints out "done" twice. This only occurs for the first obstacle.
In another script I have this:
private void OnTriggerEnter2D(Collider2D collision){
GameObject.Find("ObstacleTop").GetComponent<Obstacles>().passed = false;
}
And btw passed is set to false at the start:
public bool passed = false;
CodePudding user response:
The script is probably attached to two game objects, so it shows the log output twice.
You can see which instance the log is for by calling GetInstanceID()
in the Debug statement.
if (!passed) {
if (Player.position.x >= gameObject.GetComponent < Transform > ().position.x) {
Debug.Log(gameObject.GetInstanceID() " done");
passed = true;
}
}
CodePudding user response:
If you want to execute the code for the first object that ever executes Update
and fulfills the condition, then make the passed
variable static.
public static bool passed;
void Update()
{
if(!passed &&
Player.position.x >= gameObject.GetComponent<Transform>().position.x) {
Debug.Log("done");
passed = true;
}
}
If you make the variable static, it will exist once for this class instead of once per instance (i.e., per object).
You can also combine the two if-statements. Since C# uses short circuit evaluation, the second part of the condition (after the &&
) will not be evaluated, if the first part evaluates to false
.
CodePudding user response:
Since the flag you use to indicate whether it passed or not is not in the same scope as its accompanying if
statement, your logic will now depend on the second nested if
statement instead.
If you want to only go through this once regardless of what happens in the body, you should do something like this instead:
void Update()
{
if(!passed) {
if(Player.position.x >= gameObject.GetComponent<Transform>().position.x) {
Debug.Log("done");
}
passed = true;
}
}
This marks the block as passed as long as it has entered there at least once.