示例#1
0
    IEnumerator FindPath(Vector3 startPos, Vector3 targetPos)
    {
        Stopwatch sw = new Stopwatch();

        sw.Start();

        Vector3[] waypoints   = new Vector3[0];
        bool      pathSuccess = false;

        Node startNode  = grid.NodeFromWorldPoint(startPos);
        Node targetNode = grid.NodeFromWorldPoint(targetPos);

        startNode.parent = startNode;


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

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

                if (currentNode == targetNode)
                {
                    sw.Stop();
                    //Debug.Log("Path found: " + sw.ElapsedMilliseconds + " ms");
                    pathSuccess = true;
                    break;
                }

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

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

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

        if (pathSuccess)
        {
            waypoints = RetracePath(startNode, targetNode);
        }
        requestManager.FinishedProcessingPath(waypoints, pathSuccess);
    }
    public void FindPath(PathRequest request, Action <PathResult> callback)
    {
        Vector3[] waypoints   = new Vector3[0];
        bool      pathSuccess = false;

        Node startNode  = worldGrid.NodeFromWorldPoint(request.pathStart);
        Node targetNode = worldGrid.NodeFromWorldPoint(request.pathEnd);

        startNode.parent = startNode;
        int dist = GetDistance(startNode, targetNode);

        if (startNode.walkable && targetNode.walkable && dist > 40)
        {
            Heap <Node>    openSet   = new Heap <Node> (worldGrid.MaxSize);
            HashSet <Node> closedSet = new HashSet <Node> ();
            openSet.Add(startNode);
            while (openSet.Count > 0 && closedSet.Count < 350)
            {
                Node currentNode = openSet.RemoveFirst();
                closedSet.Add(currentNode);
                if (currentNode == targetNode)
                {
                    pathSuccess = true;
                    break;
                }

                foreach (Node neighbour in worldGrid.GetNeighbours(currentNode, request.unitCollider))
                {
                    if (!neighbour.walkable || closedSet.Contains(neighbour))
                    {
                        continue;
                    }

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

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

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

        callback(new PathResult(waypoints, pathSuccess, request.callback));
    }
    public void GetPath(Cell start, Cell end)
    {
        //Closed and open sets
        closedSet.Clear();
        open.Clear();

        //Holds result
        trajectory.Clear();
        currentDestination = end;
        ACell first = new ACell(start);

        open.Add(first);
        List <Cell> result = new List <Cell>();

        while (open.Count > 0)
        {
            //Get first node by sorting by smallest f cost and picking that
            ACell current = open[0];
            for (int i = 1; i < open.Count; i++)
            {
                if (open[i].f < current.f || (open[i].f == current.f && open[i].h < current.h))
                {
                    current = open[i];
                }
            }

            open.Remove(current);
            if (current.main == null || current == null)
            {
                continue;
            }


            closedSet.Add(current.main.worldPosition);

            if (current.main.worldPosition == end.worldPosition)
            {
                while (current != null)
                {
                    result.Insert(0, current.main);
                    current = current.parent;
                }
                trajectory = result;
                moveList   = trajectory;
                return;
            }

            List <Cell> neighbours = grid.GetNeighbours(current.main);
            foreach (Cell n in neighbours)
            {
                ACell neighbour = new ACell(n);
                if (closedSet.Contains(n.worldPosition))
                {
                    continue;
                }

                float newDistFromStart = current.g + GetDistance(current.main, n);

                if (newDistFromStart < neighbour.g || !open.Contains(neighbour))
                {
                    open.Remove(neighbour);
                    neighbour.g = newDistFromStart;

                    neighbour.h      = GetDistance(neighbour.main, end);
                    neighbour.parent = current;

                    //Remove if it exists so we can store the new updated value
                    open.Add(neighbour);
                }
            }
        }
    }
示例#4
0
    private IEnumerator FindPathEnum(Node startNode, Node targetNode, Action <List <Node>, bool> callback)
    {
        var openSet   = new Heap <Node>(grid.MaxSize);
        var closedSet = new HashSet <Node>();

        startNode.parent = startNode;
        openSet.Enqueue(startNode);
        Node currentNode;

        for (int i = 0; openSet.Count > 0; i++)
        {
            currentNode = openSet.Dequeue();
            if (currentNode == targetNode)
            {
                List <Node> path = RetracePath(startNode, targetNode);

                //draw path from targetPoint back to target
                foreach (Node n in path)
                {
                    n.ChooseAsPath();
                    toReset.Add(n);
                    yield return(new WaitForSeconds(0.1f));
                }
                path.Reverse();
                callback(path, path.Count > 0);
                yield break;
            }
            closedSet.Add(currentNode);

            foreach (Node neighbour in grid.GetNeighbours(currentNode))
            {
                if (neighbour.walkable && !closedSet.Contains(neighbour))
                {
                    int tentativeGCost = gCost(currentNode, neighbour);
                    if (tentativeGCost < neighbour.gCost || !openSet.Contains(neighbour))
                    {
                        neighbour.gCost  = tentativeGCost;
                        neighbour.hCost  = hCost(neighbour, targetNode);
                        neighbour.parent = currentNode;

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

                        neighbour.Explore();
                        toReset.Add(neighbour);
                    }
                }
            }
            //speed things up a bit
            if (i % 10 == 0)
            {
                yield return(null);
            }
        }
        foreach (Node n in toReset)
        {
            n.SetInvalid();
        }
    }