Ejemplo n.º 1
0
        public void FindPath(PathRequest request, Action <PathResult> callback)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

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

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

            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();
                        //print ("Path found: " + sw.ElapsedMilliseconds + " ms");
                        pathSuccess = true;
                        break;
                    }

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

                        float 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);
                            }
                        }
                    }
                }
            }
            if (pathSuccess)
            {
                waypoints   = RetracePath(startNode, targetNode);
                pathSuccess = waypoints.Length > 0;
            }
            callback(new PathResult(waypoints, pathSuccess, request.callback));
        }
Ejemplo n.º 2
0
        private void FindPathInternal(int requestId)
        {
            bool pathFound = false;

            PathRequestData prd      = _pathRequestDictionary[requestId];
            PathData        pathData = null;

            Node startNode = Nodes[prd.startCell.GridPosition.x, prd.startCell.GridPosition.y];
            Node endNode   = Nodes[prd.endCell.GridPosition.x, prd.endCell.GridPosition.y];

            Heap <Node>    openSet  = new Heap <Node>(_gridWidth * _gridHeight);
            HashSet <Node> closeSet = new HashSet <Node>();

            openSet.Add(startNode);

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

                if (currentNode == endNode)
                {
                    var       retracedPath = RetracePath(startNode, endNode);
                    Vector3[] waypoints    = PathToVector3Array(retracedPath);

                    if (waypoints == null)
                    {
                        retracedPath.Add(endNode);
                        waypoints = new Vector3[1] {
                            endNode.CellObj.transform.position
                        };
                    }

                    pathData = new PathData(waypoints, retracedPath);
                    prd.callback(true, pathData);
                    pathFound = true;
                    break;
                }


                foreach (Node neighbour in GetNeighbours(currentNode))
                {
                    if (closeSet.Contains(neighbour))
                    {
                        continue;
                    }

                    int hCostToNeighbor = neighbour.CellObj.Cost;

                    if (prd.ignoreTemplateList != null && neighbour.CellObj.IsOccupied)
                    {
                        if (prd.ignoreTemplateList.Count(template => template.Equals(neighbour.CellObj.Occupant.TemplateID)) > 0)
                        {
                            hCostToNeighbor = 1;
                        }
                    }

                    int movementCostToNeighbour = currentNode.GCost + hCostToNeighbor;

                    if (movementCostToNeighbour < neighbour.GCost || !openSet.Contains(neighbour))
                    {
                        neighbour.GCost = movementCostToNeighbour;
                        neighbour.HCost = GetDistance(neighbour, endNode);

                        neighbour.Parent = currentNode;

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

            if (!pathFound)
            {
                pathData = new PathData(new Vector3[1] {
                    endNode.CellObj.transform.position
                }, new List <Node>(1)
                {
                    endNode
                });
                prd.callback(false, pathData);
            }

            _pathRequestDictionary.Remove(requestId);
        }
Ejemplo n.º 3
0
        public void FindPath(PathRequest request, Action <PathResult> callback)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

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

            Node2D startNode = grid.NodeFromWorldPoint(request.pathStart);
            var    endNodes  = grid.NodesFromWorldBound(request.pathEnd, request.endBounds);

            UnityEngine.Debug.Log("nodes in end node: " + endNodes.Length);
            Node2D[] targetNode = endNodes.Where(n => n.walkable).ToArray();
            UnityEngine.Debug.Log("usable target nodes: " + targetNode.Length);
            Node2D endNode = startNode;

            try
            {
                endNode = targetNode[0];

                startNode.parent = startNode;


                if (startNode.walkable && targetNode != null && targetNode.Length > 0)
                {
                    Heap <Node2D>    openSet   = new Heap <Node2D>(grid.MaxSize);
                    HashSet <Node2D> closedSet = new HashSet <Node2D>();
                    openSet.Add(startNode);

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

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

                        foreach (Node2D 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);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                UnityEngine.Debug.Log("No usable end nodes");
                callback(new PathResult(waypoints, pathSuccess, request.callback));
            }
            if (pathSuccess)
            {
                waypoints   = RetracePath(startNode, endNode);
                pathSuccess = waypoints.Length > 0;
            }
            callback(new PathResult(waypoints, pathSuccess, request.callback));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// A* pathfinding algorithm.
        /// </summary>
        /// <param name="request">PathRequest object.</param>
        /// <param name="callback">Callback object.</param>
        public void FindPath(PathRequest request, Action <PathResult> callback)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            List <Node> waypoints   = new List <Node>();
            bool        pathSuccess = false;

            Node startNode  = _aGrid.getNode(request.pathStart);
            Node targetNode = _aGrid.getNode(request.pathEnd);

            startNode.parent = startNode;


            if (targetNode.GetState() == Enums.TileState.FREE)
            {
                Heap <Node>    openSet   = new Heap <Node>(_aGrid.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();
                        //print ("Path found: " + sw.ElapsedMilliseconds + " ms");
                        pathSuccess = true;
                        break;
                    }

                    foreach (Node neighbour in _aGrid.GetNeighbours(currentNode))
                    {
                        if (neighbour.GetState() != Enums.TileState.FREE || 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);
                            }
                        }
                    }
                }
            }

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

            callback(new PathResult(waypoints, pathSuccess, request.parameter, request.callback));
        }