- Home /
foreach script check if boolean is true
Hello, obviously I have a problem as I am asking a question. So here is my problem,
I have multiple game objects, named block. They all have the same script attached to them. In this script a boolean is set to true when these said blocks connect to each other. This boolean works as i have tested it out thoroughly.
I have another, controller object say, it's purpose is to end the game when all these blocks are connected ie, when all the booleans are true.
I have been trying to figure it out now for hours and i can't seem to find anything.
So here is some of my code:
This is attached to the controller.
obj is the gameobjects that the script with the boolean are attached to.
foreach(GameObject go in obj) //for every object
{
pcs = go.GetComponents(); //pcs of type script
}
foreach(PipeConnectorScript sc in pcs)//for each script
{
if(sc.connected == true)//if the boolean is true then win
{
won = true;
}
else
{
won = false;
}
}
if(won == true)
{
Debug.Log("Winning!");
}
Now what happens is only if some are connected then it still equals true and the log is passed. What I require is that aaallllll the booleans from each object are set to true before winning the game.
AFTER FURTHER INSPECTION
the line
pcs = go.GetComponents();
only returns one component for some reason as i have checked in the inspector. so this could be the problem. Although i do not see why as pcs is an array declared at the top like so.
PipeConnectorScript[] pcs;
I hope i have asked my question in as much detail as possible. If not then i will elaborate further, thanks much appreciated.
Answer by Samir 1 · Feb 17, 2013 at 05:48 PM
It's alll good guys i figured it out.
I was right in thinking that this line was wrong
pcs = go.GetComponents();
so i replaced it with this line and moved it into the start function.
pcs = FindObjectsOfType(typeof(PipeConnectorScript)) as PipeConnectorScript[];
as all i wanted to really do is find this script.
et voila.
Glad to see you solve your problem. However what Robertbut noticed was definitely a bug as well (you would have run into after solving the only having one component issue).
If left the way it was (without a break) you would get true if the last block check was connected regardless of whether they were all connected.
Answer by robertbu · Feb 17, 2013 at 04:38 PM
The first time you run across something that is not connected, you should break out of your loop:
foreach(PipeConnectorScript sc in pcs)//for each script
{
if(sc.connected == true)//if the boolean is true then win
{
won = true;
}
else
{
won = false;
break;
}
}
There are other ways you can structure this check, but you want to stop processing the first time you find a false. The way it is now, the your last check (T or F) is the one that sticks.
even though this may help with the code. i have tried it out and i still get the same result, the game is won even though not all are connected.
Set a break point right after the foreach exits and check the values in the list. Robertbu hit it on the head.
Another way to do what you are doing is to AND the connected together (technically still O(n), but not quite as efficient as breaking on the first false).
won = true; //set to true before checking
foreach(PipeConnectorScript sc in pcs)//for each script
{
won = won && sc.connected;
}
This is essentially the same as doing: sc1.connected & sc2.connect & sc3.connected... etc
Result should be the exact same as Robertbu's code though (only will end up being true after the loop if all the items are true).
Are you sure you're not accidentally changing the value elsewhere?
Answer by dubbreak · Feb 17, 2013 at 05:57 PM
Your problem is in your first loop. Each time you loops you are reassigning pcs with the one component from that object.
It should be something along the lines of:
foreach(GameObject go in obj) //for every object
{
pcs.Add( = GetComponent<PipeConnectorScript>()); //pcs of type script
}
You could also do this via linq:
Using System.Linq;
var pcs = objs.Where(n => n.GetComponent<PipeConnectorScript>!=null).Select(n => n.GetComponent<PipeConnectorScript>!=null).ToList();
Alternatively you can do it all in one fell swoop (since it looks like this is all in one method).
won = true;
foreach(var obj in objs)//for each script
{
var pipeScript = obj.GetComponent<PipeConnectorScript>
if (pipeScript !=null)
{
won = won && pipeScript .connected;
}
}