If ("condition in each object in an array is true")

Hello,

I’m working on a Win detection script and need to detect if all the sprites of the game objects in my array are of the same kind.

        gameObjectArray = GameObject.FindGameObjectsWithTag("RedLight"); 
        foreach (GameObject go in gameObjectArray)
            if (go.GetComponent<SpriteRenderer>().sprite == greenLight)
                Debug.Log ("YOU WIN, CONGRATULATIONS!");

I have this now but this will not work. It will print the message for each “greenLight” and not if all are “greenLight”.

How can I solve this?

Keep a boolean assuming you’ve won until proven differently.

bool victory = true;

gameObjectArray = GameObject.FindGameObjectsWithTag("RedLight");

foreach (GameObject go in gameObjectArray)
{
     if (go.GetComponent<SpriteRenderer>().sprite != greenLight)
          victory = false;
}

if(victory == true) // if it's still true, everything's a green light
    Debug.Log ("YOU WIN, CONGRATULATIONS!");

Thanks good plan! However I can’t get it working except for when i put it in update(). Is this to be expected? In any case, putting it in update() results in mega spam of the console once won.

EDIT: I’ve simply put in the WinDetection script at the end of an input script. So after every move it gets run. Now it works. Is this the right way to do this?

It seems to me like comparing sprites is a little gimmicky. You’re likely better off adding some component to your game objects that contain a boolean on whether it’s a “winning” sprite or a “losing” sprite. Instead of getting the SpriteRenderer component in the for loop you’d instead get this custom component and check the boolean. Do as @GroZZleR suggested and have a victory boolean that is true by default, and if any of your custom objects are discovered to have the bool member false (meaning it isn’t a “winning” sprite, set victory to false and break out of the for loop.

To make this work all you need to do is set the custom component’s bool to true when you change the sprite.

Don’t use GameObject.Find_______() in update… ever.

Instead you should put that in an Awake() call in that same script and set the return value to a class member of the type GameObject[ ]. The log spam is to be expected and is not a bug or problem. It’s just for testing. There’s a button in the console that will collapse repeat messages if needed.

My whole script is gimmicky probably :smile:. First game and I’m just recreating a game I remember from when I was young by using my own ideas. Thought that would be a good way to learn. Anyway thanks a lot for the suggestion. They also contribute to the learning process!

Awesome! The first game is always fun. I remember with much fondness my first game. I often want to go back to it and continue where I left off, or start over since what took me a month before I could likely do in a day now. :slight_smile:

LINQ is a great toolset to have included in your scripts for that sort of stuff:

using System.Linq;

public bool AreAllThingsInOrder()
{
    return listOfThingsThatNeedToEvalTrue.All(thing => thing.parameter == whatIexpectOfIt);
}

Cheers

Though I agree with others that you shouldn’t be tracking wins by comparing sprites and searching game objects every frame, you can use the Linq method “All()” for this:

using System.Linq;

...

if(gameObjectArray.All(go => go.GetComponent<SpriteRenderer>().sprite == greenLight))
    Debug.Log("You win");
1 Like