public void GenerateWayPoints()
    {
        for (int j = 0; j < transform.childCount; j++)
        {
            Destroy(transform.GetChild(j));
        }

        if (finishedWayPointList != null)
        {
            finishedWayPointList.Clear();
        }
        else
        {
            finishedWayPointList = new List <WayPoint>();
        }

        Vec2i startPoint = findWalkableTile();

        openWaypoints        = new List <OpenWayPoint>();
        openRoads            = new List <OpenRoad>();
        finishedWayPointList = new List <WayPoint>();

        WayPoint originalWayPoint = Instantiate(wayPointPrefab).GetComponent <WayPoint>();

        finishedWayPointList.Add(originalWayPoint);

        originalWayPoint.transform.SetParent(transform);
        originalWayPoint.transform.position   = tileMap.CellToWorld(startPoint);
        originalWayPoint.transform.localScale = Vector3.one * 2;

        int counter = 0;

        if (IsWalkable(startPoint + new Vec2i(1, 0)))
        {
            counter++;
            openRoads.Add(new OpenRoad(startPoint, new Vec2i(1, 0), originalWayPoint));
        }

        if (IsWalkable(startPoint + new Vec2i(-1, 0)))
        {
            counter++;
            openRoads.Add(new OpenRoad(startPoint, new Vec2i(-1, 0), originalWayPoint));
        }

        if (IsWalkable(startPoint + new Vec2i(0, 1)))
        {
            counter++;
            openRoads.Add(new OpenRoad(startPoint, new Vec2i(0, 1), originalWayPoint));
        }

        if (IsWalkable(startPoint + new Vec2i(0, -1)))
        {
            counter++;
            openRoads.Add(new OpenRoad(startPoint, new Vec2i(0, -1), originalWayPoint));
        }

        OpenWayPoint originalOpenWayPoint = new OpenWayPoint(startPoint, originalWayPoint, getNumberOfAdjustantWalkableTiles(startPoint));

        openWaypoints.Add(originalOpenWayPoint);

        int i = 0;

        while (openRoads.Count > 0 && i < 500)
        {
            ProcessRoad(openRoads[0]);
            i++;
        }
    }
    public void ProcessCrossRoad(Vec2i currentTile, OpenRoad incomingRoad)
    {
        int wpIndex = openWaypoints.FindIndex(wp => wp.tilePos == currentTile);

        if (wpIndex >= 0)
        {
            // add Incoming road to existing Waypoint
            if (incomingRoad.direction == new Vec2i(0, 1))
            {
                openWaypoints[wpIndex].wayPoint.down = incomingRoad.lastWayPoint;
                incomingRoad.lastWayPoint.top        = openWaypoints[wpIndex].wayPoint;
            }
            else if (incomingRoad.direction == new Vec2i(0, -1))
            {
                openWaypoints[wpIndex].wayPoint.top = incomingRoad.lastWayPoint;
                incomingRoad.lastWayPoint.down      = openWaypoints[wpIndex].wayPoint;
            }
            else if (incomingRoad.direction == new Vec2i(1, 0))
            {
                openWaypoints[wpIndex].wayPoint.left = incomingRoad.lastWayPoint;
                incomingRoad.lastWayPoint.right      = openWaypoints[wpIndex].wayPoint;
            }
            else if (incomingRoad.direction == new Vec2i(-1, 0))
            {
                openWaypoints[wpIndex].wayPoint.right = incomingRoad.lastWayPoint;
                incomingRoad.lastWayPoint.left        = openWaypoints[wpIndex].wayPoint;
            }
            int otherRoadIndex = openRoads.FindIndex(r => r.lastWayPoint == openWaypoints[wpIndex].wayPoint && (r.direction + incomingRoad.direction) == Vec2i.zero);

            //int otherRoadIndex = openRoads.FindIndex(r => r.lastWayPoint == openWaypoints[wpIndex].wayPoint);

            // remove both Roads from the openRoads
            if (otherRoadIndex >= 0)
            {
                openRoads.RemoveAt(otherRoadIndex);
                //Debug.Log("Removed OtherRoad");
                if ((++openWaypoints[wpIndex].numCheckedRoads) >= openWaypoints[wpIndex].numAdustingRoads)
                {
                    openWaypoints.RemoveAt(wpIndex);
                }
            }
            openRoads.Remove(incomingRoad);
            //Debug.Log("Removed IncomingRoad");
            OpenWayPoint otherOpenWayPoint = openWaypoints.Find(wp => wp.wayPoint == incomingRoad.lastWayPoint);

            // TODO check why this can be null?!
            if (otherOpenWayPoint != null && (++otherOpenWayPoint.numCheckedRoads) >= otherOpenWayPoint.numAdustingRoads)
            {
                openWaypoints.Remove(otherOpenWayPoint);
            }
        }
        else
        {
            // add new OpenCrossRoad
            // openWaypoints.Add(new OpenWayPoint(currentTile, ))
            WayPoint currentWP = Instantiate(wayPointPrefab).GetComponent <WayPoint>();

            currentWP.transform.SetParent(transform);
            currentWP.gameObject.transform.position = tileMap.CellToWorld(currentTile);

            finishedWayPointList.Add(currentWP);
            // Add incomingRoad to WayPoint
            // Find New Outgoing Roads and Add them to Openroads

            int outgoingRoads = 0;

            if (incomingRoad.direction == new Vec2i(1, 0))
            {
                currentWP.left = incomingRoad.lastWayPoint;
                incomingRoad.lastWayPoint.right = currentWP;
            }
            else
            {
                if (IsWalkable(currentTile + new Vec2i(-1, 0)))
                {
                    openRoads.Add(new OpenRoad(currentTile, new Vec2i(-1, 0), currentWP));
                    outgoingRoads++;
                }
            }

            if (incomingRoad.direction == new Vec2i(-1, 0))
            {
                currentWP.right = incomingRoad.lastWayPoint;
                incomingRoad.lastWayPoint.left = currentWP;
            }
            else
            {
                if (IsWalkable(currentTile + new Vec2i(1, 0)))
                {
                    openRoads.Add(new OpenRoad(currentTile, new Vec2i(1, 0), currentWP));
                    outgoingRoads++;
                }
            }

            if (incomingRoad.direction == new Vec2i(0, 1))
            {
                currentWP.down = incomingRoad.lastWayPoint;
                incomingRoad.lastWayPoint.top = currentWP;
            }
            else
            {
                if (IsWalkable(currentTile + new Vec2i(0, -1)))
                {
                    openRoads.Add(new OpenRoad(currentTile, new Vec2i(0, -1), currentWP));
                    outgoingRoads++;
                }
            }

            if (incomingRoad.direction == new Vec2i(0, -1))
            {
                currentWP.top = incomingRoad.lastWayPoint;
                incomingRoad.lastWayPoint.down = currentWP;
            }
            else
            {
                if (IsWalkable(currentTile + new Vec2i(0, 1)))
                {
                    openRoads.Add(new OpenRoad(currentTile, new Vec2i(0, 1), currentWP));
                    outgoingRoads++;
                }
            }

            OpenWayPoint openWp = new OpenWayPoint(currentTile, currentWP, outgoingRoads);
            openWaypoints.Add(openWp);
            openWp.numCheckedRoads = 0;

            OpenWayPoint otherWaypoint = openWaypoints.Find(wp => wp.wayPoint == incomingRoad.lastWayPoint);
            openRoads.Remove(incomingRoad);
            if (++(otherWaypoint.numCheckedRoads) >= otherWaypoint.numAdustingRoads)
            {
                openWaypoints.Remove(otherWaypoint);
            }
        }
    }