void OnDrawGizmosSelected()
        {
            if (grid == null)
            {
                return;
            }
            if (grid.DontDraw)
            {
                return;
            }
            if (Camera.main == null)
            {
                return;
            }

            var mousePos = Input.mousePosition;
            var pos      = Camera.main.ScreenToWorldPoint(mousePos);
            var node     = grid.NodeFromWorldPoint(pos);

            Gizmos.color = Color.green;
            Gizmos.DrawCube(grid.PosFromNode(node), Vector3.one * 0.5f);
            if (node.walkable)
            {
                Gizmos.color = Color.magenta;
                Gizmos.DrawCube(grid.PosFromNode(node), Vector3.one * 0.45f);
            }
            else
            {
                var closestNode = NodeHelper.ClosestWalkable(node, resolution);
                Gizmos.color = Color.magenta;
                Gizmos.DrawCube(grid.PosFromNode(closestNode), Vector3.one * 0.45f);
            }
        }
Exemple #2
0
        public static void GetPath(Vector2 start, Vector2 target, List <Node> pp, Resolution resolution)
        {
            #region INIT
            var grid     = NodeGridManager.GetGrid(resolution);
            var nodeGrid = grid.nodeGrid;

            Node startNode  = grid.NodeFromWorldPoint(start);
            Node targetNode = grid.NodeFromWorldPoint(target);

            if (!startNode.walkable)
            {
                startNode = NodeHelper.ClosestWalkable(startNode, resolution);
            }
            if (!targetNode.walkable)
            {
                targetNode = NodeHelper.ClosestWalkable(targetNode, resolution);
            }

            Node node, nbr;
            openSet.Clear();
            closedSet.Clear();
            openSet.Add(startNode);
            startNode.hCost = startNode.gCost = 0;
            #endregion

            while (openSet.Count > 0)
            {
                node = openSet.RemoveFirst();
                closedSet.Add(node);

                if (node == targetNode)
                {
                    pp.Clear();
                    Node currentNode = targetNode;
                    while (currentNode != startNode)
                    {
                        pp.Add(currentNode);
                        currentNode = nodeGrid[currentNode.parent.x, currentNode.parent.y];
                    }
                    pp.Reverse();
                    return;
                }

                bool skipD = false;

                var nbsA  = node.neighbours.directionNeighbours;
                int scanA = node.neighbours.DirectionCount;
                for (int i = 0; i < scanA; i++)
                {
                    nbr = nodeGrid[nbsA[i].x, nbsA[i].y];
                    if (!nbr.walkable)
                    {
                        skipD = true; continue;
                    }
                    if (closedSet.Contains(nbr))
                    {
                        continue;
                    }

                    int cost = node.gCost + heuristic(node, nbr);
                    if (!openSet.Contains(nbr))
                    {
                        nbr.gCost  = cost;
                        nbr.hCost  = heuristic(nbr, targetNode);
                        nbr.parent = new BaseNode(node.X, node.Y);
                        openSet.Add(nbr);
                    }
                    else if (cost < nbr.gCost)
                    {
                        nbr.gCost  = cost;
                        nbr.hCost  = heuristic(nbr, targetNode);
                        nbr.parent = new BaseNode(node.X, node.Y);
                    }
                }
                if (skipD)
                {
                    continue;
                }

                var nbsB  = node.neighbours.diagonalNeighbours;
                int scanB = node.neighbours.DiagonalCount;

                for (int i = 0; i < scanB; i++)
                {
                    nbr = nodeGrid[nbsB[i].x, nbsB[i].y];
                    if (!nbr.walkable)
                    {
                        continue;
                    }
                    if (closedSet.Contains(nbr))
                    {
                        continue;
                    }

                    for (int j = 0; j < nbr.neighbours.DiagonalCount; j++)
                    {
                        var nbr_D = nbr.neighbours.diagonalNeighbours[j];
                        var dNode = nodeGrid[nbr_D.x, nbr_D.y];
                        if (!dNode.walkable)
                        {
                            break;
                        }
                    }

                    int cost = node.gCost + heuristic(node, nbr);
                    if (!openSet.Contains(nbr))
                    {
                        nbr.gCost  = cost;
                        nbr.hCost  = heuristic(nbr, targetNode);
                        nbr.parent = new BaseNode(node.X, node.Y);
                        openSet.Add(nbr);
                    }
                    else if (cost < nbr.gCost)
                    {
                        nbr.gCost  = cost;
                        nbr.hCost  = heuristic(nbr, targetNode);
                        nbr.parent = new BaseNode(node.X, node.Y);
                    }
                }
            }

            // If the code escapes the while loop, it means no valid path could be found.
            Debug.LogWarning($"Path not found (Start: {start} -- Target: {target})");
        }