user13011479
user13011479

Reputation:

How to check if all objects in an array meet a requirement?

I have an array of objects of the class Target, and I have a for loop to check a statement on each of them. What I need to do is check if all of the Target scripts are shot down, which I can do by checking the value of the boolean property hasShotDown. Then, if all the Target objects in the array return true for hasShotDown, the game should end, by stopping the timer object.

    public Timer timer;

public Target[] targets;

private void Start() {
    targets = gameObject.GetComponents<Target>();
}

private void OnTriggerEnter(Collider other) {

    if (other.gameObject.layer == 9) {
        foreach (Target obj in targets) {
            if (obj.hasShotDown) {
                timer.StopTimer();
                Debug.Log("Stopped Timer and Ended game");
            }
        }
    }
}

Timer is a reference to another class, which can stop, start and display the timer. Target is another class, which holds hasShotDown. All help is appreciated, let me know if more info is needed.

Upvotes: 3

Views: 845

Answers (3)

Fattie
Fattie

Reputation: 12631

You often do it like this ...

public bool AreAnyRemaining()
{
  foreach .. of your targets
     {
     if NOT shotdown, return TRUE
     }
  return FALSE
}

Observe that this call efficiently returns TRUE if one of them has NOT been shot down.

You can then use this very easily ....

OnTriggerEnter ..
   if ( AreAnyRemaining() )
   {
      Debug.Log("play on!");
   }
   else
   {
      THEY ARE ALL SHOT DOWN - end game, etc
   }

It's that easy.

You'll see this pattern everywhere in game code.


(The way the code works in the function is called "breakaway" code. You just look until you find something, then break away and don't bother with the rest.)

Upvotes: 0

Rufus L
Rufus L

Reputation: 37020

Another way to do this using a normal foreach loop as you were doing is to create a variable to indicate that all objects have been shot down, start it out with a true value, and then set it to false if you find any object that has not been shot down yet:

private void OnTriggerEnter(Collider other) 
{
    if (other.gameObject.layer == 9) 
    {
        bool allObjectsShotDown = true;

        foreach (Target obj in targets) 
        {
            if (!obj.hasShotDown) 
            {
                allObjectsShotDown = false;
                break;
            }
        }

        if (allObjectsShotDown)
        {
            timer.StopTimer();
            Debug.Log("Stopped Timer and Ended game");
        }
    }
}

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062780

if (targets.All(obj => obj.hasShotDown)) // or .Any to test for ... "any"
{
    timer.StopTimer();
    Debug.Log("Stopped Timer and Ended game");
}

Upvotes: 7

Related Questions