Search Unity

Bug Coroutine not starting

Discussion in 'Scripting' started by VeryGoodDeveloperISwear, Mar 30, 2023.

  1. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    56
    When I run the code below, I get the "starting courotine" Debug.Log but I don't get the other Debug.Logs

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class TileSpawn : MonoBehaviour
    5. {
    6.     private Vector3 pos;
    7.     public int tilesToSpawn;
    8.     private bool isFirstTileSpawned;
    9.     private bool isStartingLoop;
    10.     private int curSquareDimensions;
    11.  
    12.     private IEnumerator courotine;
    13.  
    14.     [SerializeField] private GameObject tile;
    15.  
    16.     private void Start()
    17.     {
    18.         pos = new Vector2(0, 0);
    19.         isFirstTileSpawned = false;
    20.         courotine = SpawnTiles(3);
    21.     }
    22.     void Update()
    23.     {
    24.         if (curSquareDimensions*curSquareDimensions >= tilesToSpawn)
    25.         {
    26.             Debug.Log("starting courotine");
    27.             StopCoroutine("SpawnTiles");
    28.         }
    29.         else
    30.         {
    31.             Debug.Log("starting courotine");
    32.             StartCoroutine(courotine);
    33.         }
    34.     }
    35.  
    36.     private IEnumerator SpawnTiles(int squareDimensions)
    37.     {
    38.         Debug.Log("courotine is currently running");
    39.         tilesToSpawn = squareDimensions * squareDimensions;
    40.  
    41.         if (!isFirstTileSpawned)
    42.         {
    43.             Instantiate(tile, pos, Quaternion.identity);
    44.             Debug.Log("first tile spawned");
    45.             isFirstTileSpawned = true;
    46.             curSquareDimensions = 1;
    47.         }
    48.  
    49.         isStartingLoop = true;
    50.         if (curSquareDimensions < squareDimensions)
    51.         {
    52.             if (isStartingLoop)
    53.             {
    54.                 pos.y += 1;
    55.                 Instantiate(tile, pos, Quaternion.identity);
    56.                 curSquareDimensions += 2;
    57.                 isStartingLoop = false;
    58.             }
    59.  
    60.             //this is for making the starting top part, going right
    61.             for (int i = 0; i < (curSquareDimensions-1)/2; i++)
    62.             {
    63.                 pos.x += 1;
    64.                 Instantiate(tile, pos, Quaternion.identity);
    65.                 yield return null;
    66.             }
    67.  
    68.             //this is for making the right side
    69.             for (int i = 0; i < (curSquareDimensions-1); i++)
    70.             {
    71.                 pos.y -= 1;
    72.                 Instantiate(tile, pos, Quaternion.identity);
    73.                 yield return null;
    74.             }
    75.            
    76.             //this is for making the bottom side
    77.             for (int i = 0; i < (curSquareDimensions-1); i++)
    78.             {
    79.                 pos.x -= 1;
    80.                 Instantiate(tile, pos, Quaternion.identity);
    81.                 yield return null;
    82.             }
    83.  
    84.             //this is for making the left side
    85.             for (int i = 0; i < (curSquareDimensions-1); i++)
    86.             {
    87.                 pos.y += 1;
    88.                 Instantiate(tile, pos, Quaternion.identity);
    89.                 yield return null;
    90.             }
    91.  
    92.             //this is for making the top left side
    93.             for (int i = 0; i < (curSquareDimensions-1)/2; i++)
    94.             {
    95.                 pos.x += 1;
    96.                 Instantiate(tile, pos, Quaternion.identity);
    97.                 yield return null;
    98.             }
    99.  
    100.             pos.x += 1;
    101.             isStartingLoop = true;
    102.         }
    103.        
    104.     }
    105. }
    Also, I know that this will not work currently
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
  3. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,443
    You need to use
    courotine = StartCoroutine(SpawnTiles(3));
    - it's not a coroutine unless you tell Unity that it's a coroutine. (And spelling "coroutine" correctly will help you find and understand code better later, too.)
     
  4. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    56
    When I replaced
    courotine = SpawnTiles(3);
    with the code you provided, it gave me an error saying "Cannot implicitly convert type 'UnityEngine.Coroutine' to 'System.Collections.IEnumerator' "
     
  5. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,443
    Change the type on line 12.

    IEnumerator
    is the return value type for a coroutine. But it is not a coroutine.

    In a nutshell, these are the bits that make up code using coroutines. It's not meant for you to cut and paste into your code, just for learning from it. Kurt above already gave you plenty of documentation.

    Code (CSharp):
    1. private Coroutine coruotine;
    2.  
    3. // ...
    4.  
    5. coroutine = StartCoroutine(MyCoroutine());
    6.  
    7. // ...
    8.  
    9. StopCoroutine(coroutine);
    10.  
    11. // ...
    12.  
    13. IEnumerator MyCoroutine()
    14. {
    15.     // do stuff
    16.     yield return null;
    17.     // do more stuff
    18. }
     
  6. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    56
    Code (CSharp):
    1.     private Coroutine coroutine;
    2.  
    3.     [SerializeField] private GameObject tile;
    4.  
    5.     private void Start()
    6.     {
    7.         pos = new Vector2(0, 0);
    8.         isFirstTileSpawned = false;
    9.         coroutine = StartCoroutine(SpawnTiles(3));
    10.     }
    11.     void Update()
    12.     {
    13.         if (curSquareDimensions*curSquareDimensions >= tilesToSpawn)
    14.         {
    15.             Debug.Log("stopping courotine");
    16.             StopCoroutine(coroutine);
    17.         }
    18.         else
    19.         {
    20.             Debug.Log("starting coroutine");
    21.             _ = coroutine;
    22.         }
    23.     }
    The coroutine only runs once despite "starting coroutine" being run multiple times, why is this? (Visual Studio 2019 told me to use a discard _ to stop the error when I just do
    coroutine;
    on line 21, same result occurs when I do
    StartCoroutine(SpawnTiles(3));
    )
     
  7. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,443
    A couroutine only runs through its body once. The returned value is no longer useful once the coroutine gets to the bottom of its code, it basically stops itself when it's done. If you want to start the couroutine again, you can: just call StartCoroutine again. PLEASE read the documentation that's been given to you above.
     
  8. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Despite your log message on line 20, you are actually only ever starting the coroutine on line 9. That only happens once, in Start.
     
  9. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    56
    For my case, I want a square made of evenly sized tiles and is odd in lengths so that it has a proper center, what should I use instead of a coroutine?
     
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Coroutines and grid spawning are not even remotely related or dependent.

    If you need an example of spawning stuff in a grid, go look at my
    Bitmap2Grid
    example here:

    MakeGeo is presently hosted at these locations:

    https://bitbucket.org/kurtdekker/makegeo

    https://github.com/kurtdekker/makegeo

    https://gitlab.com/kurtdekker/makegeo

    https://sourceforge.net/p/makegeo
     
  11. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,190
    I refactored your code (with the assistance of GPT-4) to remove the coroutine. I did a rough count of the number of lines that were just boilerplate supporting the coroutine while adding nothing of value to the script and came out to at least 25 lines of code.

    Code (csharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class TileSpawn : MonoBehaviour
    5. {
    6.     private Vector3 pos;
    7.     public int tilesToSpawn;
    8.     private bool isFirstTileSpawned;
    9.     private int curSquareDimensions;
    10.  
    11.     [SerializeField] private GameObject tile;
    12.  
    13.     private void Start()
    14.     {
    15.         pos = new Vector2(0, 0);
    16.         isFirstTileSpawned = false;
    17.         SpawnTiles(3);
    18.     }
    19.  
    20.     private void SpawnTiles(int squareDimensions)
    21.     {
    22.         tilesToSpawn = squareDimensions * squareDimensions;
    23.  
    24.         if (!isFirstTileSpawned)
    25.         {
    26.             Instantiate(tile, pos, Quaternion.identity);
    27.             isFirstTileSpawned = true;
    28.             curSquareDimensions = 1;
    29.         }
    30.  
    31.         while (curSquareDimensions < squareDimensions)
    32.         {
    33.             pos.y += 1;
    34.             Instantiate(tile, pos, Quaternion.identity);
    35.             curSquareDimensions += 2;
    36.  
    37.             SpawnTileLayer();
    38.         }
    39.     }
    40.  
    41.     private void SpawnTileLayer()
    42.     {
    43.         // Starting top part, going right
    44.         for (int i = 0; i < (curSquareDimensions - 1) / 2; i++)
    45.         {
    46.             pos.x += 1;
    47.             Instantiate(tile, pos, Quaternion.identity);
    48.         }
    49.  
    50.         // Right side
    51.         for (int i = 0; i < (curSquareDimensions - 1); i++)
    52.         {
    53.             pos.y -= 1;
    54.             Instantiate(tile, pos, Quaternion.identity);
    55.         }
    56.  
    57.         // Bottom side
    58.         for (int i = 0; i < (curSquareDimensions - 1); i++)
    59.         {
    60.             pos.x -= 1;
    61.             Instantiate(tile, pos, Quaternion.identity);
    62.         }
    63.  
    64.         // Left side
    65.         for (int i = 0; i < (curSquareDimensions - 1); i++)
    66.         {
    67.             pos.y += 1;
    68.             Instantiate(tile, pos, Quaternion.identity);
    69.         }
    70.  
    71.         // Top left side
    72.         for (int i = 0; i < (curSquareDimensions - 1) / 2; i++)
    73.         {
    74.             pos.x += 1;
    75.             Instantiate(tile, pos, Quaternion.identity);
    76.         }
    77.  
    78.         pos.x += 1;
    79.     }
    80. }
     
    Last edited: Mar 30, 2023