- Home /
Foreach loop doesn't run
Hi
I'm trying to make a street intersection where I have cars going left and another group going up, in the middle has a headlight that controls when one side of the headlight is allowed and the other not. In cars there is an enum that shows which direction they will go (horizontal or vertical) and in my code I have a function calling the cars method to be added to a list, then when all cars are stored I call another method that check how many cars each side has, I do this through a foreach loop, however my foreach loop is not called, I have tried to use for and yet nothing I do enters the loop the "VerificarQuantidadeDeCarros" function is called normally.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IAFarol : MonoBehaviour
{
public bool ligarPrimeiroFarol;
public bool ligarSegundoFarol;
private bool ligado;
[SerializeField] private GameObject[] _farois = new GameObject[2];
[SerializeField] private List<GameObject> _carros = new List<GameObject>();
// Start is called before the first frame update
void Start()
{
ligarPrimeiroFarol = false;
ligarSegundoFarol = false;
for(byte i = 0; i < 2; i++)
{
_farois[i] = GameObject.Find("Farol" + (i + 1).ToString());
}
}
// Update is called once per frame
void Update()
{
if(ligarSegundoFarol && !ligado)
{
ligarPrimeiroFarol = false;
ligado = true;
Farol farol = _farois[0].GetComponent<Farol>();
Farol farol2 = _farois[1].GetComponent<Farol>();
farol.sinalDoFarol = Sinal.VERMELHO;
farol2.sinalDoFarol = Sinal.VERDE;
}
else if(ligarPrimeiroFarol)
{
ligarSegundoFarol = false;
ligado = false;
Farol farol = _farois[0].GetComponent<Farol>();
Farol farol2 = _farois[1].GetComponent<Farol>();
farol.sinalDoFarol = Sinal.VERDE;
farol2.sinalDoFarol = Sinal.VERMELHO;
}
}
public void ReceberCarro(GameObject carro)
{
_carros.Add(carro);
}
public void VerificarQuantidadeDeCarros()
{
byte _carrosNaHorizontal = 0;
byte _carrosNaVertical = 0;
foreach(GameObject carro in _carros)
{
PosFarol _posFarol = carro.GetComponent<Carros>().posFarol;
if(_posFarol == PosFarol.HORIZONTAL)
{
_carrosNaHorizontal++;
}
else if(_posFarol == PosFarol.VERTICAL)
{
_carrosNaVertical++;
}
}
Debug.Log("Verificou a quantidade de carros e mandou ligar o farol");
Debug.Log("Carros na Horizontal: " + _carrosNaHorizontal);
Debug.Log("Carros na Vertical: " + _carrosNaVertical);
_LigarFarol(_carrosNaVertical, _carrosNaHorizontal);
}
private void _LigarFarol(byte qtdCarrosVertical, byte qtdCarrosHorizontal)
{
if(qtdCarrosHorizontal > qtdCarrosVertical)
{
ligarPrimeiroFarol = true;
float ftime = (float)qtdCarrosHorizontal + 5.0f / qtdCarrosVertical;
StartCoroutine(IniciarCarros(ftime));
}
else
{
ligarSegundoFarol = true;
float ftime = (float)qtdCarrosVertical + 5.0f / qtdCarrosHorizontal;
StartCoroutine(IniciarCarros(ftime));
}
}
IEnumerator IniciarCarros(float ftime)
{
if(ligarPrimeiroFarol)
{
foreach(GameObject car in _carros)
{
Carros script = car.GetComponent<Carros>();
if (script.posFarol == PosFarol.HORIZONTAL)
{
script.podeIr = true;
}
}
}
else if(ligarSegundoFarol)
{
foreach (GameObject car in _carros)
{
Carros script = car.GetComponent<Carros>();
if (script.posFarol == PosFarol.VERTICAL)
{
script.podeIr = true;
}
}
}
yield return new WaitForSeconds(ftime);
if(ligarPrimeiroFarol)
{
ligarSegundoFarol = true;
foreach (GameObject car in _carros)
{
Carros script = car.GetComponent<Carros>();
if (script.posFarol == PosFarol.VERTICAL)
{
script.podeIr = true;
}
}
}
else if (ligarSegundoFarol)
{
ligarPrimeiroFarol = true;
foreach (GameObject car in _carros)
{
Carros script = car.GetComponent<Carros>();
if (script.posFarol == PosFarol.HORIZONTAL)
{
script.podeIr = true;
}
}
}
}
}
The foreach loop inside the VerificarQuantidadeDeCarros() method is not called? Is that it? Have you checked the size of the _carros
variable just before the loop?
Also, I recommend program$$anonymous$$g in english, it makes it easier to get help in this forums, because it helps if people understand your code entirely. I was able to understand it because I am a portuguese speaker.
Answer by Mouton · Sep 25, 2019 at 02:19 PM
If the method VerificarQuantidadeDeCarros
is called and the foreach
is not run once, there is one possibility left: the list _carros
is empty. Why depends of your code, did you correctly called ReceberCarro
before verifying the number of cars, are you sure that your coroutines don't mess with the list, filling it too late or emptying to early ?
You can remove the else if
condition for vertical vehicles since there are only 2 relevant axises to your situation, this way you will see if you have an abnormal number of vertical cars.
Thank you for your response. You was right, the cars are responsible to send themself for the script, but there is a SpawnCar script that instantiate the cars and in straight call VerificarQuantidadeDeCarros. So while the list is completed the method call them and probably is when the list is empty.
Answer by talyh · Sep 23, 2019 at 08:22 PM
I don't think it's a good idea to mix Coroutines and Foreachs. foreach
assumes a stable list, and if you're removing cars from the list as they cross the light, it'd break the foreach. That being said, I think it shouldn't prevent the loop from starting, (though maybe it does).
There's nothing in this code that seems to call ReceberCarro
(maybe there's somewhere else). Judging by this script alone, it seems the car list is always empty. So, the two questions are "is it starting the coroutine?" and "are there any cars in the list?".
I'd suggest replacing the foreach
with a for
, and adding a log with the cars count at the very beginning of the coroutine to try and identify what the issue is.
Hello
I have used a "for loop", too. But even that doesn't work, yes, that rights, the "ReceberCarro" method is called from the cars itself, so they call this method and send the gameobject for this script and I check the list when the game plays it receives all car in the scene.
I don't know if the mixing between Couroutines and Foreachs will not work because I want to know why the foreach in "VerificarQuantidadeDeCarros" aren't working.
I misunderstood the original question, thinking it was the foreach inside IniciarCarros
that wasn't working. (Though I'd still advise against a foreach inside a coroutine).
From the code alone you have there, I don't see any reason why the loop inside VerificarQuantidadeDeCarros
won't run. I don't see a call for that function anywhere in this code, so I'm assu$$anonymous$$g it's called elsewhere too. If that's the case, I'd guess the loop is running, but the issue is something else (for instance, an exception being thrown on PosFarol _posFarol = carro.GetComponent<Carros>().posFarol;
due to a non-car being mistakenly added to the list).
Thank you for give your time to help me, ms Talyh, but I already managed to resolve, the problem was I'm not give the appropriate time to fill the list and call the method.
Your answer
Follow this Question
Related Questions
Checking an array variable in C# vs JavaScript 3 Answers
Foreach loop inside FileStream 1 Answer
Array Element in Foreach loop 1 Answer