示例#1
0
    private IEnumerator FollowPlayer()
    {
        while (true)
        {
            yield return(waitForNewPath);

            if (playerTransform == null)
            {
                playerTransform = GameObject.FindGameObjectWithTag("Player").GetComponent <Transform>();
            }
            closeToPlayerNodes = Physics.OverlapSphere(playerTransform.position, inaccuracy, walkableMask);
            int randomNode = UnityEngine.Random.Range(1, closeToPlayerNodes.Length - 1);
            try
            {
                pathRequest = new PathRequestData(thisTransform.position, closeToPlayerNodes[randomNode].transform.position, PathSubmitted);
            }
            catch
            {
                print("<color=blue>Path request data can't be set up!</color>");
            }
            try
            {
                pathManager.RequestPath(pathRequest);
            }
            catch
            {
                print("<color=blue>Path request failed!</color>");
            }
        }
    }
示例#2
0
    // Request a new path to start on a new thread
    public static void RequestThreadPath(PathRequestData request)
    {
        // Starts this delegate on a new a thread
        ThreadStart threadStart = delegate
        {
            // From the main instance (Singleton instance), call the path-finding method
            _instance._pathFindingManager.FindPath(request, _instance.FinishedProcessingThreadPath);
        };

        threadStart.Invoke();   // Invoke the thread
    }
示例#3
0
 public void RequestPath(PathRequestData pathRequest)
 {
     pathfinding.FindPathFromAtoB(pathRequest);
 }
示例#4
0
    public void FindPath(PathRequestData requestData, Action <PathResultData> callbackAction)
    {
        Stopwatch sw = new Stopwatch(); /* Used in order to see the performance of the path-finding system before/after heap tree optimization.
                                         *           Stopwatch creates some kind of overhead so disable it in the final build.*/

        sw.Start();
        // CallbackPathResult elements
        Vector2[] pathWayPoints = new Vector2[0];
        bool      pathSuccess   = false;

        #region A* Algorithm
        // Find the start and end nodes on the current grid system
        Node startNode  = _gridSystem.NodeFromWorldPoint(requestData.PathStart);
        Node targetNode = _gridSystem.NodeFromWorldPoint(requestData.PathEnd);
        // Only do calculations if nodes are walkable
        if (/*startNode.Walkable &&*/ targetNode.Walkable)
        {
            HeapTree <Node> openNodeSet   = new HeapTree <Node>(_gridSystem.MaxHeapSize); // Binary Heap Tree for A* iteration - optimization
            HashSet <Node>  closedNodeSet = new HashSet <Node>();                         // Hash Set for the closed node set of the A* algorithm
            //
            openNodeSet.AddItem(startNode);                                               // Begin with the starting node
            while (openNodeSet.HeapTreeSize > 0)                                          // While the open node set is not empty
            {
                Node currentNode = openNodeSet.RemoveFirst();                             // First in heap tree is the one with the lowest score.
                closedNodeSet.Add(currentNode);                                           // Transfer this node from open set to closed set
                if (currentNode == targetNode)                                            // PathResult status check - if the target node is reached
                {
                    sw.Stop();
                    print("Path found in : " + sw.ElapsedMilliseconds + " mili-seconds ");
                    pathSuccess = true;

                    break; // PathResult has been found. Exit the while loop
                }          // If not found start neighbor cost calculations

                // List of the adjacent neighboring nodes. They are pre-calculated and stored in Nodes - optimization (Heap -> Stack Memory Allocation)
                List <Node> neighborNodeSet = currentNode.NeighborNodes;  // Get the pre-computed neighbor nodes
                for (int i = 0; i < neighborNodeSet.Count; i++)
                {
                    if (!neighborNodeSet[i].Walkable || closedNodeSet.Contains(neighborNodeSet[i]))
                    {
                        continue; // Non-walkable nodes and already closed nodes are passed
                    }
                    // New movement G cost with the path through current node
                    int movementCostToNeighbor = currentNode.GCost + GetDistance(currentNode, neighborNodeSet[i]);
                    // If the new distance from starting node is shorter and open node set does not contain this neighbor
                    if (movementCostToNeighbor < neighborNodeSet[i].GCost || !openNodeSet.ContainsItem(neighborNodeSet[i]))
                    {
                        neighborNodeSet[i].GCost      = movementCostToNeighbor; // Update the distance from starting node with its new path
                        neighborNodeSet[i].HCost      = GetDistance(neighborNodeSet[i], targetNode);
                        neighborNodeSet[i].ParentNode = currentNode;            // Set the new parent of the node for final path detection
                        if (!openNodeSet.ContainsItem(neighborNodeSet[i]))      // If it is not in the open set, add it to the set
                        {
                            openNodeSet.AddItem(neighborNodeSet[i]);
                        }
                        else
                        {
                            openNodeSet.UpdateItem(neighborNodeSet[i]); // If already in the set then the values are changed
                        }
                    }
                }
            }
        }
        #endregion

        // If an available path is found
        if (pathSuccess)
        {
            pathWayPoints = ReTracePath(startNode, targetNode);     // Find the path way-points by re-tracing parent nodes
            pathSuccess   = pathWayPoints.Length > 0;               // Set path to success if there is at least one way-point
        }

        // Trigger the callback, path is found. This will trigger the queue in the path-finding request manager
        callbackAction(new PathResultData(pathWayPoints, _wayPointNodesCache, pathSuccess, requestData.CallbackPathRequest));
    }
示例#5
0
        public void Update(int maxIter = 100)
        {
            var             s      = state[0];
            PathQueryStatus status = PathQueryStatus.Success;

            if (s.entitySize == 0)
            {
                return;
            }
            while (maxIter > 0)
            {
                if (s.entityInUse == State.NONE)
                {
                    PathRequestData request = requests[0];
                    for (int i = s.entitySize - 1; i >= 0; --i)
                    {
                        request = requests[i];
                        if (request.status < PathRequestStatus.Done)
                        {
                            s.entityInUse = i;
                            break;
                        }
                    }
                    if (s.entityInUse == State.NONE)
                    {
                        break;
                    }
                    var startLoc = query.MapLocation(request.start, Vector3.one * 10f, request.agentType, request.mask);
                    var endLoc   = query.MapLocation(request.end, Vector3.one * 10f, request.agentType, request.mask);
                    status = query.BeginFindPath(startLoc, endLoc, request.mask);
                    if (status.IsFailure())
                    {
                        break;
                    }
                    request.status          = PathRequestStatus.InProgress;
                    requests[s.entityInUse] = request;
                }
                int nIter;
                status = query.UpdateFindPath(maxIter, out nIter);
                if (status.IsFailure())
                {
                    break;
                }
                maxIter -= nIter;
                if (status.IsSuccess())
                {
                    int pathSize;
                    var request = requests[s.entityInUse];
                    status = query.EndFindPath(out pathSize);
                    if (status.IsFailure())
                    {
                        break;
                    }
                    if (status.IsSuccess())
                    {
                        query.GetPathResult(resultBuffer);
                        var offset    = s.pathSize;
                        var pathSlice = new NativeSlice <PathPoint>(pathBuffer, offset);
                        status = PathUtils.FindStraightPath(query, request.start, request.end, resultBuffer, pathSize
                                                            , pathSlice, ref pathSize, MAX_PATHSIZE);
                        if (status.IsFailure())
                        {
                            break;
                        }
                        pathStart[s.entityInUse] = offset;
                        request.pathSize         = pathSize;
                        s.pathSize += pathSize;
                    }
                    request.status          = PathRequestStatus.Done;
                    requests[s.entityInUse] = request;
                    s.entityInUse           = State.NONE;
                }
                state[0] = s;
            }

            if (status.IsFailure())
            {
                var request = requests[s.entityInUse];
                request.status          = PathRequestStatus.Failure;
                requests[s.entityInUse] = request;
                s.entityInUse           = State.NONE;
                state[0] = s;
            }
        }
示例#6
0
    public void FindPathFromAtoB(PathRequestData pathRequest)
    {
        ASNode startNode  = grid.GetNodeFromWorldPoint(pathRequest.startPos);
        ASNode finishNode = grid.GetNodeFromWorldPoint(pathRequest.finishPos);

        if (finishNode.walkable == false)
        {
            return;
        }
        List <ASNode>    openNodes   = new List <ASNode>();
        HashSet <ASNode> closedNodes = new HashSet <ASNode>();

        openNodes.Add(startNode);

        while (openNodes.Count > 0)
        {
            ASNode currentNode = openNodes[0];
            for (int i = 1; i < openNodes.Count; i++)
            {
                if (openNodes[i].FCost < currentNode.FCost || openNodes[i].FCost == currentNode.FCost && openNodes[i].hCost < currentNode.hCost)
                {
                    if (openNodes[i].hCost < currentNode.hCost)
                    {
                        currentNode = openNodes[i];
                    }
                }
            }

            openNodes.Remove(currentNode);
            closedNodes.Add(currentNode);

            if (currentNode == finishNode)
            {
                RetracePath(startNode, finishNode);
                pathRequest.pathGetter(path);
                return;
            }

            foreach (ASNode neighbour in grid.GetNodeNeighbors(currentNode))
            {
                if (!neighbour.walkable || closedNodes.Contains(neighbour))
                {
                    continue;
                }

                int newGCostToNeighbour = currentNode.gCost + GetManhattanDistance(currentNode, neighbour);

                if (newGCostToNeighbour < neighbour.gCost || !openNodes.Contains(neighbour))
                {
                    neighbour.gCost      = newGCostToNeighbour;
                    neighbour.hCost      = GetManhattanDistance(neighbour, finishNode);
                    neighbour.parentNode = currentNode;

                    if (!openNodes.Contains(neighbour))
                    {
                        openNodes.Add(neighbour);
                    }
                }
            }
        }
    }
示例#7
0
文件: Squad.cs 项目: 2push/RTS
    public void AttackBase(Base target)
    {
        PathRequestData pathRequest = new PathRequestData(transform.position, target.StartNode.transform.position, Move);

        pathManager.RequestPath(pathRequest);
    }