public static void FillUnitLists(int width, int height, List <RecursiveBacktrackingCalculationUnit> allUnitList, List <RecursiveBacktrackingCalculationUnit> pathUnitList)
    {
        //Total number of cells that needs to be initialized and added.
        int limit = width * height;

        for (int i = 0; i < limit; i++)
        {
            int cellWidth  = i % width;
            int cellHeight = i / width;
            int oddOrEven  = ((i / width) % 2 == 0) ? 0 : 1;

            BaseCell baseCell = new BaseCell(new Vector2(cellWidth, cellHeight));

            RecursiveBacktrackingCalculationUnit unit = new RecursiveBacktrackingCalculationUnit(baseCell, width, height)
            {
                isVisited = false,
                isWall    = true
            };
            if (cellHeight % 2 == 1)
            {
                allUnitList.Add(unit);
            }
            //Every unit on a even spot is going to be a path unit.
            else if (i % 2 == oddOrEven)
            {
                unit.isWall = false;
                allUnitList.Add(unit);
                pathUnitList.Add(unit);
            }
            else
            {
                allUnitList.Add(unit);
            }
        }
    }
    //using await Task.Delay to prevent algortihm freezing the whole programme when the calculation takes to long to process in a single frame.
    public async static Task <List <Vector2Int> > CalculateRecursiveBacktrackingMaze(Vector2Int mazeDimensions)
    {
        List <RecursiveBacktrackingCalculationUnit> allUnits  = new List <RecursiveBacktrackingCalculationUnit>();
        List <RecursiveBacktrackingCalculationUnit> pathUnits = new List <RecursiveBacktrackingCalculationUnit>();

        FillUnitLists(mazeDimensions.x, mazeDimensions.y, allUnits, pathUnits);

        //Make the initial unit the current unit and mark it as visited
        RecursiveBacktrackingCalculationUnit         startingUnit  = pathUnits[(UnityEngine.Random.Range(0, (int)mazeDimensions.y))];
        RecursiveBacktrackingCalculationUnit         currentUnit   = startingUnit;
        Stack <RecursiveBacktrackingCalculationUnit> pathUnitStack = new Stack <RecursiveBacktrackingCalculationUnit>();

        currentUnit.isVisited = true;

        //While there are unvisited units
        while (pathUnits.Count != 0)
        {           //If the current unit has any neighbours which have not been visited
            if (ReturnUnvistedNeighbours(currentUnit, allUnits, ToolMethods.RowColumnSearch, (int)mazeDimensions.x).Count != 0)
            {
                //Randomly choose one of the unvistedNeightbours
                List <RecursiveBacktrackingCalculationUnit> unvistedNeightbours         = ReturnUnvistedNeighbours(currentUnit, allUnits, ToolMethods.RowColumnSearch, (int)mazeDimensions.x);
                RecursiveBacktrackingCalculationUnit        RandomlyChosenNeighbourUnit = unvistedNeightbours[UnityEngine.Random.Range(0, unvistedNeightbours.Count)];
                pathUnitStack.Push(currentUnit);
                currentUnit.isWall = false;
                RandomlyChosenNeighbourUnit.isWall = false;
                //Make the wall between the chosen unit and the current unit a pathUnit.
                RecursiveBacktrackingCalculationUnit wallCell = FindTheInBetweenWall(RandomlyChosenNeighbourUnit, allUnits, ToolMethods.RowColumnSearch, (int)mazeDimensions.x);
                wallCell.isWall = false;
                pathUnits.Remove(currentUnit);
                currentUnit           = RandomlyChosenNeighbourUnit;
                currentUnit.isVisited = true;
            }
            else if (pathUnitStack.Count != 0)
            {
                currentUnit = pathUnitStack.Pop();
            }
            // If there are somehow units that couldn't be reached by the process above.
            else
            {
                //Choose one of the remaining unit and repeat the process
                RecursiveBacktrackingCalculationUnit reviveUnit = pathUnits[UnityEngine.Random.Range(0, pathUnits.Count)];
                currentUnit = reviveUnit;
                pathUnits.Remove(reviveUnit);
                currentUnit.isVisited = true;
            }
            await Task.Delay(1);
        }
        List <Vector2Int> positions = new List <Vector2Int>();

        foreach (RecursiveBacktrackingCalculationUnit cellToSpawn in allUnits)
        {
            if (cellToSpawn.isWall)
            {
                positions.Add(new Vector2Int((int)cellToSpawn.BaseCell.Position.x, (int)cellToSpawn.BaseCell.Position.y));
            }
        }
        return(positions);
    }
    public static RecursiveBacktrackingCalculationUnit FindTheInBetweenWall(RecursiveBacktrackingCalculationUnit cellOnTheOtherSide, List <RecursiveBacktrackingCalculationUnit> cellCollectionToSearchFrom,
                                                                            Func <int, int, int, int> listSearchAlgorithmToUse, int mazeWidth)
    {
        RecursiveBacktrackingCalculationUnit wallCell = null;

        int directionCellX = (int)cellOnTheOtherSide.ThroughWhatDirectionWasIFound.x;

        if (Mathf.Abs(directionCellX) > 0)
        {
            directionCellX = directionCellX / 2;
        }
        int directionCellY = (int)cellOnTheOtherSide.ThroughWhatDirectionWasIFound.y;

        if (Mathf.Abs(directionCellY) > 0)
        {
            directionCellY = directionCellY / 2;
        }
        wallCell = cellCollectionToSearchFrom[listSearchAlgorithmToUse(mazeWidth, (int)cellOnTheOtherSide.BaseCell.Position.x - directionCellX,
                                                                       (int)cellOnTheOtherSide.BaseCell.Position.y - directionCellY)];
        return(wallCell);
    }
    public static List <RecursiveBacktrackingCalculationUnit> ReturnUnvistedNeighbours(RecursiveBacktrackingCalculationUnit currentcell, List <RecursiveBacktrackingCalculationUnit> cellCollectionToSearchFrom,
                                                                                       Func <int, int, int, int> listSearchAlgorithmToUse, int mazeWidth)
    {
        List <RecursiveBacktrackingCalculationUnit> unvistedNeighbours = new List <RecursiveBacktrackingCalculationUnit>();
        int i = 0;

        foreach (KeyValuePair <string, Vector2> direction in RecursiveBacktrackingDirections.directions)
        {
            if (currentcell.AvailableNeighbourDirections[i])
            {
                Vector2 neighbourPosition = currentcell.BaseCell.Position + direction.Value;
                RecursiveBacktrackingCalculationUnit NeighbourCell = cellCollectionToSearchFrom[listSearchAlgorithmToUse(mazeWidth, (int)neighbourPosition.x, (int)neighbourPosition.y)];
                if (!NeighbourCell.isVisited)
                {
                    unvistedNeighbours.Add(NeighbourCell);
                    NeighbourCell.ThroughWhatDirectionWasIFound = direction.Value;
                }
            }
            i++;
        }
        return(unvistedNeighbours);
    }