- Home /
Both IF statements in a function are run and their conditions are ignored.
Hello all, I am building obstacles, these two example obstacles could be controlled by my script:
Scenario One - The player triggers a collider and a door object is deactivated, the player has a certain amount of time to get to the door before it closes (the object is re-activated).
Scenario Two - Similar to scenario one but instead of a door object being deactivated, a bridge object is activated and then the player has an amount of time to cross the bridge before it is deactivated.
I am trying to write a script to run this obstacle in my game, the script has two states, one for each Scenario to make the script have multiple uses that are basically the same (I need my state bool to be changeable within the inspector panel):
State 1 (When "activateObjectInstead" is false) - Deactivate object, wait for (time) seconds, then activate object.
State 2 (When "activateObjectInstead" is true) - Activate object, wait for (time) seconds, then deactivate the object.
I'd like the state of a bool to be checked and that would decide what state/scenario the script would follow. I have written a script however it seems that both my IF statements get activated, here is my script:
#pragma strict
//State 1 (When "activateObjectInstead" is false) - Deactivate object, wait for (time) seconds, then activate object.
//State 2 (When "activateObjectInstead" is true) - Activate object, wait for (time) seconds, then deactivate the object.
var object : GameObject; //The object that will be activated or deactivated by the script.
var controller : GameObject;
var buttonmodel : GameObject;
var time : int;
var activateObjectInstead : boolean; //The bool that decides what state the script will run.
var soundOne : AudioClip;
var soundTwo : AudioClip;
public var soundvolume : float = 0.5;
function OnTriggerEnter(collision : Collider) {
if (collision.gameObject.tag == (controller));
{
if (activateObjectInstead == false); //Only if "activateObjectInstead" is false.
{
object.SetActive(false); //Deactivate the object.
buttonmodel.SetActive(false);
AudioSource.PlayClipAtPoint(soundOne, transform.position, soundvolume);
Debug.Log("Set Inactive");
yield WaitForSeconds (time); //Wait for (time) seconds.
object.SetActive(true); //Reactivate the object.
buttonmodel.SetActive(true);
udioSource.PlayClipAtPoint(soundTwo, transform.position, soundvolume);
Debug.Log("Set Active");
}
if (activateObjectInstead == true); //Only if "activateObjectInstead" is true.
{
object.SetActive(true); //Activate the object.
buttonmodel.SetActive(false);
AudioSource.PlayClipAtPoint(soundTwo, transform.position, soundvolume);
Debug.Log("Set Inactive");
yield WaitForSeconds (time); //Wait for (time) seconds.
object.SetActive(false); //Deactivate the object.
buttonmodel.SetActive(true);
AudioSource.PlayClipAtPoint(soundOne, transform.position, soundvolume);
Debug.Log("Set Active");
}
}
}
Answer by JSierraAKAMC · Feb 11, 2017 at 10:28 PM
You're comparing the collision object's tag (a string) to the 'controller' variable, which is a GameObject. The reason it does something when there's a semicolon after the if statements is because it will run the code no matter what. To fix this, try fixing these things:
//// other code
function OnTriggerEnter(collision : Collider) {
if (collision.gameObject.tag == "controller") {
if(!activateObjectInstead){ //In other words, if it is NOT true
//// other code
//// If you want to see if this code is called, insert Debug.Log("Collided and false"); here
}
if(activateObjectInstead) { //In other words, if it IS true
//// other code
//// If you want to see if this code is called, insert Debug.Log("Collided and true"); here
}
}
}
This should fix some of the problems. Be sure to change your character controller's tag to "controller" or else it will not work. Alternatively, you can compare the collision object's tag to the controller variable's tag with the following:
if (collision.gameObject.tag == controller.tag) {
//// CODE
}
Thank you for your help, finally got around to implementing this fix! I changed the controller variable after the == to a variable called controllerTag and then changed the old controller variable type from GameObject to String, then I added a controller tag to my player controller and it works as intended! Thanks again, much appreciated.
Answer by tanoshimi · Feb 11, 2017 at 09:39 PM
Remove the semicolons at the end of all your if statements:
if (collision.gameObject.tag == (controller));
should be
if (collision.gameObject.tag == (controller))
Otherwise, the only thing being affected by the if condition is the empty statement terminated by the semicolon.
On removing the semicolons, the script does absolutely nothing, with them, the IF statements do some sort of action, without them its like there's not even a script.
That's not what's going on there. The semicolons mean that the blocks immediately following the "if" lines are not connected to the "if" condition, so they are always executed. In other words it's not that the semicolons make the "if" statements do something it's that they make them do nothing.
You definitely want to remove the semicolons, but that's not the only issue (see the other answers about the tag comparison).
If you dont believe, you can check for yourself
void Update() {
if (false); {
Debug.Log("hi");
}
}
Then try removing the semicolon after the")"
Answer by Comrade_Tito · Feb 11, 2017 at 11:42 PM
Hey Ronan!
I think I see something that I don't find very clear in your code... the IF statement that holds the other two...
if (collision.gameObject.tag == (controller));
controller is a variable of the type GameObject. Thus, to compare a game object tag I think you should use collision.gameObject.tag == controller.tag
Secondly... why put a semicolon after every condition. Semicolons shouldn't be put after conditions because they are a delimiter used to end a command line. Everything after a semicolon is regarded as the next line in code.
Hope I helped!
Answer by kevindang · Feb 12, 2017 at 09:05 AM
I think the problem is that you haven’t actually set the value of your boolean once you hit the collider.
So when you do collide with the object that triggers whether the door or bridge is deactivated/activated, you haven’t specified what's supposed to happen (i.e. what if statement to go into!).
I also think it’s possible to just have one if statement that controls whether the door/bridge has been activated or not. Yes, it makes logical sense for you to separate it into two different if statements as the door is the one that deactivates and the bridge is the one that's activating, but the computer doesn’t need to know this difference. One if statement that evaluates to true, will suffice for both functionalities.
So, I think if you do something like this, it could work:
if (collision.gameObject.tag == (controller)) {
activateObjectInstead = true; // specify what you want the value to be when the player hits the collider
if (activateObjectInstead == true) {
// do something with special object (door/bridge = deactivate)
} else { // activateObjectInstead == false
// opposite would happen (door/bridge = activate)
}
}
The value of the bool is set via the inspector panel, I did declare the variable after the variable however but read that values set in the inspector overwrite the coded values.
And thank you, I just put them in different statements to make it simple to understand.