Coroutine not starting

When I run the code below, I get the “starting courotine” Debug.Log but I don’t get the other Debug.Logs

using System.Collections;
using UnityEngine;

public class TileSpawn : MonoBehaviour
{
    private Vector3 pos;
    public int tilesToSpawn;
    private bool isFirstTileSpawned;
    private bool isStartingLoop;
    private int curSquareDimensions;

    private IEnumerator courotine;

    [SerializeField] private GameObject tile;

    private void Start()
    {
        pos = new Vector2(0, 0);
        isFirstTileSpawned = false;
        courotine = SpawnTiles(3);
    }
    void Update()
    {
        if (curSquareDimensions*curSquareDimensions >= tilesToSpawn)
        {
            Debug.Log("starting courotine");
            StopCoroutine("SpawnTiles");
        }
        else
        {
            Debug.Log("starting courotine");
            StartCoroutine(courotine);
        }
    }

    private IEnumerator SpawnTiles(int squareDimensions)
    {
        Debug.Log("courotine is currently running");
        tilesToSpawn = squareDimensions * squareDimensions;

        if (!isFirstTileSpawned)
        {
            Instantiate(tile, pos, Quaternion.identity);
            Debug.Log("first tile spawned");
            isFirstTileSpawned = true;
            curSquareDimensions = 1;
        }

        isStartingLoop = true;
        if (curSquareDimensions < squareDimensions)
        {
            if (isStartingLoop)
            {
                pos.y += 1;
                Instantiate(tile, pos, Quaternion.identity);
                curSquareDimensions += 2;
                isStartingLoop = false;
            }

            //this is for making the starting top part, going right
            for (int i = 0; i < (curSquareDimensions-1)/2; i++)
            {
                pos.x += 1;
                Instantiate(tile, pos, Quaternion.identity);
                yield return null;
            }

            //this is for making the right side
            for (int i = 0; i < (curSquareDimensions-1); i++)
            {
                pos.y -= 1;
                Instantiate(tile, pos, Quaternion.identity);
                yield return null;
            }
           
            //this is for making the bottom side
            for (int i = 0; i < (curSquareDimensions-1); i++)
            {
                pos.x -= 1;
                Instantiate(tile, pos, Quaternion.identity);
                yield return null;
            }

            //this is for making the left side
            for (int i = 0; i < (curSquareDimensions-1); i++)
            {
                pos.y += 1;
                Instantiate(tile, pos, Quaternion.identity);
                yield return null;
            }

            //this is for making the top left side
            for (int i = 0; i < (curSquareDimensions-1)/2; i++)
            {
                pos.x += 1;
                Instantiate(tile, pos, Quaternion.identity);
                yield return null;
            }

            pos.x += 1;
            isStartingLoop = true;
        }
       
    }
}

Also, I know that this will not work currently

Coroutines in a nutshell:

Splitting up larger tasks in coroutines:

Coroutines are NOT always an appropriate solution: know when to use them!

Our very own Bunny83 has also provided a Coroutine Crash Course:

https://answers.unity.com/questions/1749615/coroutines-ienumerator-not-working-as-expected.html?childToView=1749714#answer-1749714

1 Like

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.)

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’ "

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.

private Coroutine coruotine;

// ...

coroutine = StartCoroutine(MyCoroutine());

// ...

StopCoroutine(coroutine);

// ...

IEnumerator MyCoroutine()
{
    // do stuff
    yield return null;
    // do more stuff
}
    private Coroutine coroutine;

    [SerializeField] private GameObject tile;

    private void Start()
    {
        pos = new Vector2(0, 0);
        isFirstTileSpawned = false;
        coroutine = StartCoroutine(SpawnTiles(3));
    }
    void Update()
    {
        if (curSquareDimensions*curSquareDimensions >= tilesToSpawn)
        {
            Debug.Log("stopping courotine");
            StopCoroutine(coroutine);
        }
        else
        {
            Debug.Log("starting coroutine");
            _ = coroutine;
        }
    }

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));)

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.

Despite your log message on line 20, you are actually only ever starting the coroutine on line 9. That only happens once, in Start.

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?

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

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.

Refactored Script

using System.Collections;
using UnityEngine;

public class TileSpawn : MonoBehaviour
{
    private Vector3 pos;
    public int tilesToSpawn;
    private bool isFirstTileSpawned;
    private int curSquareDimensions;

    [SerializeField] private GameObject tile;

    private void Start()
    {
        pos = new Vector2(0, 0);
        isFirstTileSpawned = false;
        SpawnTiles(3);
    }

    private void SpawnTiles(int squareDimensions)
    {
        tilesToSpawn = squareDimensions * squareDimensions;

        if (!isFirstTileSpawned)
        {
            Instantiate(tile, pos, Quaternion.identity);
            isFirstTileSpawned = true;
            curSquareDimensions = 1;
        }

        while (curSquareDimensions < squareDimensions)
        {
            pos.y += 1;
            Instantiate(tile, pos, Quaternion.identity);
            curSquareDimensions += 2;

            SpawnTileLayer();
        }
    }

    private void SpawnTileLayer()
    {
        // Starting top part, going right
        for (int i = 0; i < (curSquareDimensions - 1) / 2; i++)
        {
            pos.x += 1;
            Instantiate(tile, pos, Quaternion.identity);
        }

        // Right side
        for (int i = 0; i < (curSquareDimensions - 1); i++)
        {
            pos.y -= 1;
            Instantiate(tile, pos, Quaternion.identity);
        }

        // Bottom side
        for (int i = 0; i < (curSquareDimensions - 1); i++)
        {
            pos.x -= 1;
            Instantiate(tile, pos, Quaternion.identity);
        }

        // Left side
        for (int i = 0; i < (curSquareDimensions - 1); i++)
        {
            pos.y += 1;
            Instantiate(tile, pos, Quaternion.identity);
        }

        // Top left side
        for (int i = 0; i < (curSquareDimensions - 1) / 2; i++)
        {
            pos.x += 1;
            Instantiate(tile, pos, Quaternion.identity);
        }

        pos.x += 1;
    }
}