How does unity thread work?

Since it contains lots of code it would be longer sry
I’m making a maze generator. After Start(), A System generates the cells recursively. I want a system to implement a BuildNavMesh for the last time. but when Cell.ColorNext() is called, the thread doesn’t wait there and keeps going. How do I let the system implement the method when a recursive function is done? or How do I know when the recursive method is done? ( I tried the stack, but it doesn’t be zero.)

This is a code for generating a random path and making the enemy follow the player without collides with a wall.

public class MazeCreator: MonoBehaviour
    {
    public int width;
    public int col;
    public int row;
    public Vector3 startPos;
    public Material mat;
    public GameObject cell;
    public Stack<Cell> stack = new Stack<Cell>();
    public NavMeshSurface NavMesh;
 
    public List<List<Cell>> rowList = new List<List<Cell>>();


    public Cell currentCell;

    public bool isSleep = true;
    // Start is called before the first frame update
    void Start()
    {
        for(int i=0; i< row; i++)
        {
            //Step1 : fill the columns
            List<Cell> columnList = new List<Cell>();
            for (int j=0; j<col; j++)
            {
                //step 2 create and init the cell.
                Cell newCell = new Cell();
                newCell.cell = Instantiate(cell, startPos, cell.transform.rotation);
                columnList.Add(newCell);
                newCell.InitCell(i,j,this);
             
                //step3 move to next pos.
                startPos.x += width;
            }

            //step4 fill the rows with the columns.
            rowList.Add(columnList);

            //step5 move to the next row and go to the first pos of a column.
            startPos.x -= col * width;
            startPos.z += width;
        }

        isSleep = true;
        //next, set the currentcell and draw it recursively.
        currentCell = rowList[0][0];
        currentCell.isVisited = true;
        currentCell.show();
        currentCell.ColorNext(currentCell);
        stack.Push(currentCell);

        StartCoroutine(BuildNavMesh());
     
     

    }

    public IEnumerator BuildNavMesh()
    {
     
     

        foreach (List<Cell> clist in rowList)
        {
            foreach (Cell c in clist)
            {
                c.ground.SetActive(false);
            }
        }


        NavMesh.BuildNavMesh();
        Debug.Log("Builded");

        yield return new WaitForSeconds(0.1f);
    }
    //method for measuring a time.
    public void Wait( Cell next)
    {
        StartCoroutine(wait(next));
    }
    IEnumerator wait( Cell next)
    {
        yield return new WaitForSeconds(0.2f);
        next.ColorNext(next);
    }

    // Update is called once per frame
    void Update()
        {
     
        }
    }

    public class Cell
    {
    public int i;
    public int j;
    public bool bottom;
    public bool top;
    public bool left;
    public bool right;

    public Material matSelected;

    public GameObject leftWall;
    public GameObject rightWall;
    public GameObject topWall;
    public GameObject bottomWall;
    public GameObject ground;

    public bool isVisited = false;
    public Cell current;

    public GameObject cell;
    public MazeCreator maze;
    public Material mat;


    public List<Cell> neighbors = new List<Cell>();
    public Cell checkNeighbors(Cell cell)
    {
     
        // first, init the position of a cell.
        i = cell.i;
        j = cell.j;
     
        // case for exceeding a left margin.
        if (j - 1 >= 0)
        {
            Cell left = maze.rowList[j - 1];
            if (!left.isVisited) neighbors.Add(left);
        }


        //case for exceeding a right margin.
        if (j + 1 < maze.col)
        {
            Cell right = maze.rowList[j + 1];
            if (!right.isVisited) neighbors.Add(right);

        }

        //case for exceeding a top margin.
        if (i - 1 >= 0)
        {
            Cell top = maze.rowList[i - 1][j];
            if (!top.isVisited) neighbors.Add(top);
        }

        //case for exceeding a bottom margin.
        if (i + 1 < maze.row)
        {
            Cell bottom = maze.rowList[i + 1][j];
            if (!bottom.isVisited) neighbors.Add(bottom);
        }

        //check the cell has any neighbors.
        if (neighbors.Count > 0)
        {
            Cell neighbor = neighbors[Random.Range(0, neighbors.Count)];
         
            return neighbor;
        }

        return null;

     




    }
    public void InitCell(int i, int j, MazeCreator maze)
    {
        this.i = i;
        this.j = j;

        //set the maze ,current cell and walls.
        this.maze = maze;
        this.current = this;
        leftWall = cell.transform.GetChild(0).gameObject;
        rightWall = cell.transform.GetChild(1).gameObject;
        topWall = cell.transform.GetChild(2).gameObject;
        bottomWall = cell.transform.GetChild(3).gameObject;
        ground = cell.transform.GetChild(4).gameObject;

    }
    public void show()
    {
        //draw the cell
        if (isVisited)
        {
            leftWall.GetComponent<MeshRenderer>().materials[0].color = Color.blue;
            rightWall.GetComponent<MeshRenderer>().materials[0].color = Color.blue;
            topWall.GetComponent<MeshRenderer>().materials[0].color = Color.blue;
            bottomWall.GetComponent<MeshRenderer>().materials[0].color = Color.blue;
         

        }
        if (left)
        {
            leftWall.SetActive(true);
        }

        if (right)
        {
            rightWall.SetActive(true);
        }

        if (top)
        {
            topWall.SetActive(true);
        }

        if (bottom)
        {
            bottomWall.SetActive(true);
        }
    }

    public void ColorNext(Cell cell)
    {

        ground.GetComponent<MeshRenderer>().materials[0].color = Color.black;
        //get the neighbor cell


        Cell next = checkNeighbors(cell);
     
        if (next != null)
        {
         
            //visit first and show it.
            //step1
            next.isVisited = true;
            next.show();
            next.ground.GetComponent<MeshRenderer>().materials[0].color = Color.yellow;
            maze.stack.Push(next);
            //step3
            removeWalls(cell, next);


            //step4
            maze.Wait(next);
            //next.ColorNext(next);
         

         
        }

     
     
        //case getting stuck : no neighbors exist. + stack is not empty.
        if (next == null && maze.stack.Count > 0)
        {
         
         
            while (next == null)
            {
                //first, pop from the stack, and check its neighbor until it has neighbor.
                current = (Cell)maze.stack.Pop();
                current.ground.GetComponent<MeshRenderer>().materials[0].color = Color.green;
                next  = checkNeighbors(current);
                //next.ground.GetComponent<MeshRenderer>().materials[0].color = Color.yellow;


            }

            next.isVisited = true;
            next.show();
            ColorNext(next);

        }

    }

    public void removeWalls(Cell current, Cell next)
    {
        int h = current.i - next.i;
        int v = current.j - next.j;

        //Right
        if(v < 0)
        {
            current.rightWall.SetActive(false);
            next.leftWall.SetActive(false);
        }

        //Left
        else if(v > 0)
        {
            current.leftWall.SetActive(false);
            next.rightWall.SetActive(false);
        }

        //Bottom
        else if(h > 0)
        {
            current.bottomWall.SetActive(false);
            next.topWall.SetActive(false);
        }

        //Top
        else if ( h < 0)
        {
            current.topWall.SetActive(false);
            next.bottomWall.SetActive(false);
        }
    }



    }

7284601–880735–MazeCreator.cs (7.69 KB)

Please read this and use code tags so people can actually help you.

3 Likes

OOh. Thanks!

Does anybody know the solution pls let me know

This has nothing to do with threads, at least from the code posted above.

It sounds like there may be a bug in your maze logic.

To track it down, I would reduce your maze size down to the smallest maze dimensions that manifest the problem and start debugging it.

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?

Knowing this information will help you reason about the behavior you are seeing.

You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

https://discussions.unity.com/t/839300/3

2 Likes

I solved it. it was the problem of a condition, for next != null. and building different ways navmesh was worked.