Example #1
0
        public static Stack <Node> SearchPath(Node startNode, Node endNode)
        {
            if (startNode == null || endNode == null)
            {
                return(null);
            }

            HashSet <Node> openSet     = new HashSet <Node>();
            HashSet <Node> closedSet   = new HashSet <Node>();
            Node           currentNode = startNode;

            currentNode.SetFirstNodeValues();
            openSet.Add(currentNode);

            while (openSet.Count > 0)
            {
                currentNode = LookForLowerF(openSet);
                if (currentNode == endNode)
                {
                    break;
                }

                for (int i = 0, neighbourCount = currentNode.Neighbours.Count; i < neighbourCount; i++)
                {
                    Node neighNode = currentNode.Neighbours[i];

                    if (!neighNode.IsTransitable || closedSet.Contains(neighNode))
                    {
                        continue;
                    }

                    if (!openSet.Contains(neighNode))
                    {
                        openSet.Add(neighNode);
                        neighNode.Parent = currentNode;
                        neighNode.G      = CalculateG(currentNode, neighNode);
                        neighNode.H      = CalculateH(neighNode, endNode);
                    }
                    else
                    {
                        float potentialG = CalculateG(currentNode, neighNode);
                        if (potentialG < neighNode.G)
                        {
                            neighNode.Parent = currentNode;
                            neighNode.G      = potentialG;
                        }
                    }
                }
                openSet.Remove(currentNode);
                closedSet.Add(currentNode);
            }

            if (currentNode == endNode)
            {
                Node sourceNode = startNode;
                Node targetNode = endNode;

                while (sourceNode != targetNode)
                {
                    Vector3 from = sourceNode.transform.position;
                    Vector3 dir  = targetNode.transform.position - from;

                    RaycastHit hit;
                    if (Physics.Raycast(from, dir.normalized, out hit, dir.magnitude))
                    {
                        if (targetNode.Parent != null && targetNode != targetNode.Parent)
                        {
                            targetNode = targetNode.Parent;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        targetNode.Parent = sourceNode;
                        sourceNode        = targetNode;
                        targetNode        = endNode;
                    }
                }

                return(RebuildRoad(endNode));
            }
            else
            {
                Debug.Log("Impossible to find a way. The node may be an island");
                return(null);
            }
        }