private void Update()
    {
        if (Input.GetMouseButtonDown(0) && debugMod)
        {
            DebugDrawer.Clear();
            debugPoint   = Input.mousePosition;
            debugPoint.x = Screen.width - debugPoint.x;
            StartCoroutine(Render());
        }

        if (Input.GetKeyDown(KeyCode.S) && !debugMod)
        {
            StartCoroutine(Render());
        }

        if (DebugDrawer.isDebug != debugMod)
        {
            DebugDrawer.isDebug = debugMod;
        }
    }
    public void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            var position    = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            var positionInt = new Vector3Int((int)position.x, (int)position.y, 0);

            Debug.Log("Clicked at: " + positionInt.x + " - " + positionInt.y);

            /*var tile = Ground.GetTile(positionInt);
             *
             * if (tile == walkable)
             * {
             *  Ground.SetTile(positionInt, blocked);
             * }
             * else if (tile == blocked)
             * {
             *  Ground.SetTile(positionInt, road);
             * }
             * else if (tile == road)
             * {
             *  Ground.SetTile(positionInt, walkable);
             * }*/
        }
        else if (Input.GetMouseButtonDown(1))
        {
            var position    = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            var positionInt = new Vector3Int((int)position.x, (int)position.y, 0);
            if (has(end) == false && has(start))
            {
                Path.SetTile(positionInt, end);
            }
            else
            {
                DebugDrawer.Clear();
                Path.ClearAllTiles();
                Path.SetTile(positionInt, start);
            }
        }
    }
    public void FindPath(bool astar)
    {
        DebugDrawer.Clear();

        // Convert visible grid to memory grid
        var grid     = GridController.Ground;
        var pathGrid = GridController.Path;

        var sizeX = GridController.active.size.x;
        var sizeY = GridController.active.size.y;

        var memoryGrid = createGraph();
        // Set grid weights
        var start = new Vector2Int(-1, -1);
        var end   = new Vector2Int(-1, -1);

        for (var x = 0; x < sizeX; x++)
        {
            for (var y = 0; y < sizeY; y++)
            {
                var pathTile = pathGrid.GetTile(new Vector3Int(x, y, 0));
                if (pathTile != null)
                {
                    if (pathTile == GridController.active.start)
                    {
                        start = new Vector2Int(x, y);
                    }
                    else if (pathTile == GridController.active.end)
                    {
                        end = new Vector2Int(x, y);
                    }
                }
            }
        }

        if (start.x == -1 || end.x == -1)
        {
            Debug.Log("Couldn't find any start or end position");
            return;
        }

        List <Node> path;

        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        if (astar)
        {
            var asearch = new AStarSearch();
            sw.Start();
            path = asearch.GetPath(memoryGrid, start, end);
            UnityEngine.Debug.Log("A* Path - Path" + (path == null ? " not " : " ") + "found in : " + sw.ElapsedMilliseconds + " ms");
        }
        else
        {
            var jpsearch = new JumpPointSearch();
            sw.Start();
            path = jpsearch.GetPath(memoryGrid, start, end);
            UnityEngine.Debug.Log("JPS Path - Path" + (path == null ? " not " : " ") + "found in : " + sw.ElapsedMilliseconds + " ms");
        }

        if (path != null)
        {
            foreach (var pathTile in path)
            {
                if (pathTile.x == start.x && pathTile.y == start.y)
                {
                    continue;
                }
                if (pathTile.x == end.x && pathTile.y == end.y)
                {
                    continue;
                }

                if (pathTile.parent != null)
                {
                    DebugDrawer.Draw(new Vector2Int(pathTile.parent.x, pathTile.parent.y), new Vector2Int(pathTile.x, pathTile.y), Color.blue);
                }
                DebugDrawer.DrawCube(new Vector2Int(pathTile.x, pathTile.y), Vector2Int.one, Color.blue);
            }
        }
    }
    public void FindSubGoalPath()
    {
        DebugDrawer.Clear();

        // Convert visible grid to memory grid
        var grid     = GridController.Ground;
        var pathGrid = GridController.Path;

        var sizeX = GridController.active.size.x;
        var sizeY = GridController.active.size.y;

        var memoryGrid = createGraph();
        // Set grid weights
        var start = new Vector2Int(-1, -1);
        var end   = new Vector2Int(-1, -1);

        for (var x = 0; x < sizeX; x++)
        {
            for (var y = 0; y < sizeY; y++)
            {
                var pathTile = pathGrid.GetTile(new Vector3Int(x, y, 0));
                if (pathTile != null)
                {
                    if (pathTile == GridController.active.start)
                    {
                        start = new Vector2Int(x, y);
                    }
                    else if (pathTile == GridController.active.end)
                    {
                        end = new Vector2Int(x, y);
                    }
                }
            }
        }

        if (start.x == -1 || end.x == -1)
        {
            Debug.Log("Couldn't find any start or end position");
            return;
        }

        // List<Node> path;
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();

        SubGoalGrid sgg = new SubGoalGrid(memoryGrid);

        sgg.ConstructSubgoals(0, 0, sizeX, sizeY);
        sgg.ConstructEdges(0, 0, sizeX, sizeY);

        Debug.Log(sgg.subGoals.Count);

        sw.Stop();
        Debug.Log("Preprocessing took " + sw.ElapsedMilliseconds + "ms");
        sgg.DrawSubGoals();

        List <Node> path;
        var         subGoalSearch = new SubGoalAStarSearch(sgg);

        sw.Restart();
        path = subGoalSearch.GetPath(sgg, start, end);
        UnityEngine.Debug.Log("SubGoalSearch Path - Path" + (path == null ? " not " : " ") + "found in : " + sw.ElapsedMilliseconds + " ms");

        if (path != null)
        {
            foreach (var pathTile in path)
            {
                if (pathTile.x == start.x && pathTile.y == start.y)
                {
                    continue;
                }
                if (pathTile.x == end.x && pathTile.y == end.y)
                {
                    continue;
                }

                if (pathTile.parent != null)
                {
                    DebugDrawer.Draw(new Vector2Int(pathTile.parent.x, pathTile.parent.y), new Vector2Int(pathTile.x, pathTile.y), Color.blue);
                }
                DebugDrawer.DrawCube(new Vector2Int(pathTile.x, pathTile.y), Vector2Int.one, Color.blue);
            }
        }
    }
    public void FindBiDirectionalDijkstraPath()
    {
        DebugDrawer.Clear();
        var pathGrid   = GridController.Path;
        var memoryGrid = createGraph();

        var sizeX = GridController.active.size.x;
        var sizeY = GridController.active.size.y;
        // Set grid weights
        var start = new Vector2Int(-1, -1);
        var end   = new Vector2Int(-1, -1);

        for (var x = 0; x < sizeX; x++)
        {
            for (var y = 0; y < sizeY; y++)
            {
                var pathTile = pathGrid.GetTile(new Vector3Int(x, y, 0));
                if (pathTile != null)
                {
                    if (pathTile == GridController.active.start)
                    {
                        start = new Vector2Int(x, y);
                    }
                    else if (pathTile == GridController.active.end)
                    {
                        end = new Vector2Int(x, y);
                    }
                }
            }
        }

        if (start.x == -1 || end.x == -1)
        {
            Debug.Log("Couldn't find any start or end position");
            return;
        }

        // List<Node> path;
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();

        List <BiDirectionalDijkstraSearch.Node> path;
        var biDirectionalDijkstra = new BiDirectionalDijkstraSearch(memoryGrid);

        path = biDirectionalDijkstra.GetPath(start, end);
        UnityEngine.Debug.Log("BiDirectionalDijkstraSearch Path - Path" + (path == null ? " not " : " ") + "found in : " + sw.ElapsedMilliseconds + " ms");

        if (path != null)
        {
            foreach (var pathTile in path)
            {
                if (pathTile.x == start.x && pathTile.y == start.y)
                {
                    continue;
                }
                if (pathTile.x == end.x && pathTile.y == end.y)
                {
                    continue;
                }

                DebugDrawer.DrawCube(new Vector2Int(pathTile.x, pathTile.y), Vector2Int.one, Color.blue);
            }
        }
    }
    public void FindMultiLevelPath()
    {
        DebugDrawer.Clear();
        var pathGrid   = GridController.Path;
        var memoryGrid = createGraph();
        var graph      = new OverlayGraph(memoryGrid);

        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        graph.BuildChunk(0);
        graph.BuildChunk(1);
        graph.BuildChunk(2);
        graph.BuildChunk(3);
        UnityEngine.Debug.Log("MultiLayerGraph Building took " + sw.ElapsedMilliseconds + " ms");

        var sizeX = GridController.active.size.x;
        var sizeY = GridController.active.size.y;

        // Set grid weights
        var start = new Vector2Int(-1, -1);
        var end   = new Vector2Int(-1, -1);

        for (var x = 0; x < sizeX; x++)
        {
            for (var y = 0; y < sizeY; y++)
            {
                var pathTile = pathGrid.GetTile(new Vector3Int(x, y, 0));
                if (pathTile != null)
                {
                    if (pathTile == GridController.active.start)
                    {
                        start = new Vector2Int(x, y);
                    }
                    else if (pathTile == GridController.active.end)
                    {
                        end = new Vector2Int(x, y);
                    }
                }
            }
        }

        if (start.x == -1 || end.x == -1)
        {
            Debug.Log("Couldn't find any start or end position");
            return;
        }

        sw.Restart();

        List <OverlayGraphPathfinder.GraphNode> path;
        var pathfinder = new OverlayGraphPathfinder(graph);

        path = pathfinder.BidirectionalDijkstra(start.x, start.y, end.x, end.y);
        UnityEngine.Debug.Log("MultiLayerGraph - Path" + (path == null ? " not " : " ") + "found in : " + sw.ElapsedMilliseconds + " ms");

        //  graph.DrawCellBorders();
        // graph.DrawOverlayGraph(1);

        // graph.DrawGraph();
        // overlayGraph.DrawGraph();

        if (path != null)
        {
            foreach (var pathTile in path)
            {
                var chunk = graph.GetChunk(pathTile.ChunkID);
                int gridPosition;
                if (pathTile.QueryLevel > 0)
                {
                    gridPosition = chunk.vertices[chunk.overlayVertices[pathTile.VertexID].OriginalVertex].GridPosition;
                }
                else
                {
                    gridPosition = chunk.vertices[pathTile.VertexID].GridPosition;
                }

                var x = gridPosition / graph.sizeY;
                var y = gridPosition % graph.sizeY;
                if (x == start.x && y == start.y)
                {
                    continue;
                }
                if (x == end.x && y == end.y)
                {
                    continue;
                }

                DebugDrawer.DrawCube(new Vector2Int(x, y), Vector2Int.one, Color.blue);
            }
        }
    }
 public void Clear()
 {
     DebugDrawer.Clear();
 }