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. Dismiss Notice

Problem with foreach loops and lists

Discussion in 'Scripting' started by Adjaar7, Jan 19, 2021.

  1. Adjaar7

    Adjaar7

    Joined:
    Jan 6, 2020
    Posts:
    22
    I have a robot in a topdown game that moves one tile randomly. His movement is stored in a list, because I want the player to have to copy his movements. Each movement is remembered, so that his list of moves gets longer and harder to follow. The problem is that in the foreach loop, all of his movements are applied at once.

    Here's what I mean.
    Code (CSharp):
    1.           foreach (Vector3 pos in pattern)
    2.           {
    3.               robot.Translate(pos);
    4.               Debug.Log(pos);
    5.           }
    the patterns are added correctly, for instance the console might say something like:
    (1, 0, 0)
    (-1, 0, 0)
    (0, 1, 0)

    but all the movements are applied at the same time, so in this example he looks like he moves one space up instead of right, left, up.

    I think I must be not understanding how foreach loops work, but I can't think of a way to fix this. I hope my problem is clear enough, I'll be glad to clarify
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    That certianly seems to be the case. There's nothing about a for loop that says "stop and wait for some amount of time between iterations." As with all code, Unity will blaze through it as fast as possible. If you want that kind of behavior, coroutines are a simple way to do it:
    Code (CSharp):
    1. // in your other code...
    2. StartCoroutine(ApplyMotionOverTime(pattern));
    3.  
    4. ...
    5.  
    6. IEnumerator ApplyMotionOverTime(List<Vector3> pattern) {
    7.     foreach (Vector3 pos in pattern)
    8.     {
    9.       robot.Translate(pos);
    10.       Debug.Log(pos);
    11.       // This tells Unity to actually wait for some time before continuing. It only works inside coroutines.
    12.       yield return new WaitForSeconds(1f);
    13.     }
    14. }
     
  3. Adjaar7

    Adjaar7

    Joined:
    Jan 6, 2020
    Posts:
    22
    Thanks! Exactly what I needed. Funnily enough I had a coroutine in the script that called that method. It wasn't really doing anything before that so I got rid of it and put it here. I should also mention that it didn't work until I encased the foreach loop within in While(true) loop. It only called once before then