예제 #1
0
    private IEnumerator PathSearch()
    {
        while (!grid.GridGenerated)
        {
            yield return(new WaitForSeconds(0.5f));
        }

        PathNode targetNode = grid.GetNearestWalkableNode(request.pathEnd);
        PathNode startNode  = grid.GetNearestWalkableNode(request.pathStart);

        waypoints = new Vector3[0];
        pathFound = false;

        if (startNode.walkable && targetNode.walkable)
        {
            Heap <PathNode>    openSet   = new Heap <PathNode>(grid.MaxSize);
            HashSet <PathNode> closedSet = new HashSet <PathNode>();
            openSet.Add(startNode);

            float timer   = Time.realtimeSinceStartup;
            float maxTime = .01f;
            while (openSet.Count > 0)
            {
                if (Time.realtimeSinceStartup > timer + maxTime)
                {
                    yield return(null);

                    timer = Time.realtimeSinceStartup;
                }
                PathNode currentNode = openSet.RemoveFirst();
                closedSet.Add(currentNode);

                if (currentNode == targetNode)
                {
                    pathFound = true;
                    break;
                }

                foreach (PathNode neighbour in grid.GetNeighbours(currentNode))
                {
                    if (!neighbour.walkable || closedSet.Contains(neighbour))
                    {
                        continue;
                    }

                    int newMoveCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) + currentNode.movementPenalty;
                    if (newMoveCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                    {
                        neighbour.gCost  = newMoveCostToNeighbour;
                        neighbour.hCost  = GetDistance(neighbour, targetNode);
                        neighbour.parent = currentNode;

                        if (!openSet.Contains(neighbour))
                        {
                            openSet.Add(neighbour);
                        }
                        else
                        {
                            openSet.UpdateItem(neighbour);
                        }
                    }
                }
            }
        }

        if (pathFound)
        {
            waypoints = RetracePath(startNode, targetNode);
            pathFound = waypoints.Length > 0;
        }
    }