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)