Is having a "break" in a "foreach" loop that is itself inside a "for" loop breaking both loops?

Hi dear members,

Is having a “break” in a “foreach” loop -that is itself inside a “for” loop- breaking both loops (foreach is the direct one where the “break” command is called, but foreach is itself nested in a for loop) or only the direct one (foreach)?

I get no errors, but the behavior is not EXACTLY how I intend it to be, so I am wondering if the problem can originate from how the break command behaves… I want to stop the foreach loop on break, however the for loop should go on until g<4.

Part of my code I wonder about:

for (g=1;g<4;g++)
{
    if (g == 1)
    {
        gos = GameObject.FindGameObjectsWithTag("crabtag");
    }
    else if (g == 2) {
        gos = GameObject.FindGameObjectsWithTag("turtletag");
    }
    else if (g == 3)
    {
        gos = GameObject.FindGameObjectsWithTag("jellytag");
    }

    foreach(GameObject go in gos)
    {
        if (playerposx == go.transform.position.x && playerposy == go.transform.position.y)
        {
            if (g == 1)
            {
                crabHere = true;
                break;
            }
            else if (g == 2)
            {
                turtleHere = true;
                break;
            }
            else if (g == 3)
            {
                jellyHere = true;
                break;
            }
        }
        else
        {
            if (g == 1)
            {
                crabHere = false;
            }
            else if (g == 2) 
            {
                turtleHere = false;
            } 
            else if (g == 3)
            {
                jellyHere = false;
            }
        }
    }
}

Just to post a clear answer to the question: no :wink:

Breaking within a loop will break only the exact loop you’re in, without considering its parents.

As Mike states, the code is hard to read in its current formatting and appears to be linked. As a helpful hint to the future, try to keep only one entry and one exit to every loop/method, multiple breaks and continues can render code hard to debug.

To answer your question: No, there is nothing wrong with the break statement.

But your code logic looks a bit weird. Try to make a dedicated method instead of series of if... else. Something like:

public enum Animal { Crab, Turtle, Jelly }

// ...

void MainMethod(Vector3 playerPosition)
{
    crabHere = CheckAnimal(Animal.Crab, playerPosition);
    turtleHere = CheckAnimal(Animal.Turtle, playerPosition);
    jellyHere = CheckAnimal(Animal.Jelly, playerPosition);
}

bool CheckAnimal(Animal animal, Vector3 playerPosition)
{
    GameObject[] gos = null;
    switch (animal)
    {
    default:
        return false;

    case Crab:
        gos = GameObject.FindGameObjectsWithTag("crabtag");
        break;

    case Turtle:
        gos = GameObject.FindGameObjectsWithTag("turtletag");
        break;

    case Jelly:
        gos = GameObject.FindGameObjectsWithTag("jellytag");
        break;
    }

    if (!gos || gos.Length == 0)
    {
        return false;
    }

    foreach(GameObject go in gos)
    {
        if (playerPosition.x == go.transform.position.x && playerPosition.y == go.transform.position.y)
        {
            return true;
        }
    }

    return false;
}

The main problems with your code were:

  1. Hard to read.

  2. Hard to debug.

  3. Float comparison as @fafase pointed out. You should consider using Mathf.Approximately or use Vector.sqrMagnitude:

    if (playerPosition - go.transform.position).sqrMagnitude < 1.0f