Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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

Discussion in 'Scripting' started by farayman3, Apr 14, 2015.

  1. farayman3

    farayman3

    Joined:
    Apr 11, 2015
    Posts:
    5
    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.
    Code (CSharp):
    1.         gameObjectArray = GameObject.FindGameObjectsWithTag("RedLight");
    2.         foreach (GameObject go in gameObjectArray)
    3.             if (go.GetComponent<SpriteRenderer>().sprite == greenLight)
    4.                 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?
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Keep a boolean assuming you've won until proven differently.

    Code (csharp):
    1.  
    2. bool victory = true;
    3.  
    4. gameObjectArray = GameObject.FindGameObjectsWithTag("RedLight");
    5.  
    6. foreach (GameObject go in gameObjectArray)
    7. {
    8.      if (go.GetComponent<SpriteRenderer>().sprite != greenLight)
    9.           victory = false;
    10. }
    11.  
    12. if(victory == true) // if it's still true, everything's a green light
    13.     Debug.Log ("YOU WIN, CONGRATULATIONS!");
    14.  
     
  3. farayman3

    farayman3

    Joined:
    Apr 11, 2015
    Posts:
    5
    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?
     
  4. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    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.
     
  5. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    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.
     
  6. farayman3

    farayman3

    Joined:
    Apr 11, 2015
    Posts:
    5
    My whole script is gimmicky probably :D. 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!
     
  7. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    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. :)
     
  8. HarvesteR

    HarvesteR

    Joined:
    May 22, 2009
    Posts:
    525
    LINQ is a great toolset to have included in your scripts for that sort of stuff:

    Code (csharp):
    1.  
    2. using System.Linq;
    3.  
    4. public bool AreAllThingsInOrder()
    5. {
    6.     return listOfThingsThatNeedToEvalTrue.All(thing => thing.parameter == whatIexpectOfIt);
    7. }
    8.  
    9.  
    Cheers
     
  9. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    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:

    Code (csharp):
    1. using System.Linq;
    2.  
    3. ...
    4.  
    5. if(gameObjectArray.All(go => go.GetComponent<SpriteRenderer>().sprite == greenLight))
    6.     Debug.Log("You win");
     
    gunsmac likes this.