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

        stopwatch.Start();

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

        CNode startNode = grid.GetNodeFromWorldPoint(request.pathStart);
        CNode endNode   = grid.GetNodeFromWorldPoint(request.pathEnd);

        if (startNode.walkable && endNode.walkable)
        {
            CHeap <CNode>   openSet   = new CHeap <CNode>(grid.MaxSize);
            HashSet <CNode> closedSet = new HashSet <CNode>();

            openSet.Add(startNode);

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

                if (currentNode == endNode)
                {
                    stopwatch.Stop();
                    print("Path found: " + stopwatch.ElapsedMilliseconds + " ms");
                    pathSuccess = true;
                    break;
                }

                foreach (CNode 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, endNode);
                        neighbour.parent = currentNode;

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

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

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