public static List <NavMeshCell> CalculateNavMeshCells(Grid grid) { NavMeshCell.ResetMeshIDs(); Grid = grid; for (int col = 0; col < Grid.Cols; col++) { for (int row = 0; row < Grid.Rows; row++) { Grid[col, row].MeshID = Cell.NOT_PART_OF_MESH; } } startAt = new Point(Grid.Cols / 2, Grid.Rows / 2); Grid[startAt].Passable = true; //startAt = new Point(0, 0); finishedCalculating = false; blockedEast = false; blockedSouth = false; blockedWest = false; blockedNorth = false; navCells = new List <NavMeshCell>(); curCell = new NavMeshCell(Grid[startAt].Pos, Grid.CellSize, Grid.CellSize); frontier = new List <Cell>(); while (!finishedCalculating) { // If cell is becoming long and skinny, restrict expansion on that axis. // Restrict East / West expansion if (curCell.Width >= curCell.Height * 3) { blockedEast = true; blockedWest = true; } // Restrict North / South expansion if (curCell.Height >= curCell.Width * 3) { blockedNorth = true; blockedSouth = true; } // Try to expand east. if (!blockedEast) { blockedEast = DoNewCellsBlock(GetNextEastCol(curCell)); // Expansion is valid. if (!blockedEast) { // Increase size of current cell. curCell.Width += Grid.CellSize; } } // Try to expand south. if (!blockedSouth) { blockedSouth = DoNewCellsBlock(GetNextSouthRow(curCell)); // Expansion is valid if (!blockedSouth) { // Increase size of current cell. curCell.Height += Grid.CellSize; } } // Try to expand west. if (!blockedWest) { blockedWest = DoNewCellsBlock(GetNextWestCol(curCell)); // Expansion is valid if (!blockedWest) { // Increase size of current cell. curCell.Width += Grid.CellSize; curCell.Pos.X -= Grid.CellSize; } } // Try to expand north. if (!blockedNorth) { blockedNorth = DoNewCellsBlock(GetNextNorthRow(curCell)); // Expansion is valid. if (!blockedNorth) { // Increase size of current cell. curCell.Height += Grid.CellSize; curCell.Pos.Y -= Grid.CellSize; } } // Blocked on both dimensinos, finalise this nav mesh cell. if (BlockedOnAllSides) { // Finish making this cell and start making a new one. // Probably calculate neighbours here too. uint nextMeshID = NavMeshCell.NextMeshID; curCell.NavMeshID = nextMeshID; AddNavCell(curCell); // Assign each cell in the area as part of the new Nav Mesh Cell. foreach (Cell c in Grid.CellsInRect(curCell.CollisionRect.GetInflated(-1, -1))) { c.MeshID = nextMeshID; } // Update frontier to remove any cells now part of the mesh for (int i = frontier.Count - 1; i >= 0; i--) { if (frontier[i].MeshID != Cell.NOT_PART_OF_MESH) { frontier.RemoveAt(i); } } // Get surrounding cells. var newCells = GetNextBorder(curCell); foreach (Cell c in newCells) { // Add to frontier if valid if (c.Passable && c.MeshID == Cell.NOT_PART_OF_MESH) { frontier.Add(c); } } if (frontier.Count == 0) { finishedCalculating = true; } if (!finishedCalculating) { startAt = Grid.IndexAt(frontier[0].Mid); curCell = new NavMeshCell(Grid[startAt].Pos, Grid.CellSize, Grid.CellSize); blockedEast = false; blockedSouth = false; blockedNorth = false; blockedWest = false; } } } CalculateNeighbours(); return(navCells); }