Esempio n. 1
0
    public List <NodeNew> GetNeighbours(NodeNew node)
    {
        List <NodeNew> neighbours = new List <NodeNew>();

        for (int x = -1; x <= 1; x++)
        {
            for (int y = -1; y <= 1; y++)
            {
                if (x == 0 && y == 0)
                {
                    continue;
                }
                //if (x != 0 && y != 0) //Ignores diagonal neighbors
                //	continue;

                int checkX = node.gridX + x;
                int checkY = node.gridY + y;

                if (checkX >= 0 && checkX < gridSizeX && checkY >= 0 && checkY < gridSizeY)
                {
                    neighbours.Add(grid[checkX, checkY]);
                }
            }
        }

        return(neighbours);
    }
    IEnumerator FindPath(Vector3 startPos, Vector3 targetPos)       //Calculate the path
    {
        Vector3[] waypoints   = new Vector3[0];
        bool      pathSuccess = false;

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

        //if (startNode.walkable && targetNode.walkable) {
        if (startNode.walkable && targetNode.walkable)           //Removed startNode (under the assumption objects will never be inside a wall, which is unwalkable.)
        {
            HeapNew <NodeNew> openSet   = new HeapNew <NodeNew>(grid.MaxSize);
            HashSet <NodeNew> closedSet = new HashSet <NodeNew>();
            openSet.Add(startNode);

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

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

                foreach (NodeNew neighbour in grid.GetNeighbours(currentNode))
                {
                    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);
                        }
                    }
                }
            }
        }
        yield return(null);

        if (pathSuccess)
        {
            waypoints = RetracePath(startNode, targetNode);
        }
        requestManager.FinishedProcessingPath(waypoints, pathSuccess);
    }
    int GetDistance(NodeNew nodeA, NodeNew nodeB)
    {
        int dstX = Mathf.Abs(nodeA.gridX - nodeB.gridX);
        int dstY = Mathf.Abs(nodeA.gridY - nodeB.gridY);

        if (dstX > dstY)
        {
            return(14 * dstY + 10 * (dstX - dstY));
        }
        return(14 * dstX + 10 * (dstY - dstX));
    }
    Vector3[] RetracePath(NodeNew startNode, NodeNew endNode)
    {
        List <NodeNew> path        = new List <NodeNew>();
        NodeNew        currentNode = endNode;

        while (currentNode != startNode)
        {
            path.Add(currentNode);
            currentNode = currentNode.parent;
        }
        Vector3[] waypoints = SimplifyPath(path, startNode);
        Array.Reverse(waypoints);
        return(waypoints);
    }
Esempio n. 5
0
    public void CreateGrid()
    {
        grid = new NodeNew[gridSizeX, gridSizeY];
        Vector3 worldBottomLeft = transform.position - Vector3.right * gridWorldSize.x / 2 - Vector3.forward * gridWorldSize.y / 2;     //*** Vector3 forward to up

        for (int x = 0; x < gridSizeX; x++)
        {
            for (int y = 0; y < gridSizeY; y++)
            {
                Vector3    worldPoint = worldBottomLeft + Vector3.right * (x * nodeDiameter + nodeRadius) + Vector3.forward * (y * nodeDiameter + nodeRadius);              // ***
                RaycastHit hit;
                bool       walkable = new bool();
                if (Physics.Raycast(worldPoint, Vector3.down, out hit, rayMask))                 //Only checks raycast on these layers
                {
                    walkable = !(Physics.CheckSphere(hit.point, nodeRadius, unwalkableMask));
                }
                //walkable = !(Physics.CheckSphere(worldPoint,nodeRadius,unwalkableMask)); //Default
                grid[x, y] = new NodeNew(walkable, worldPoint, x, y);
            }
        }
    }
    Vector3[] SimplifyPath(List <NodeNew> path, NodeNew startNode)
    {
        List <Vector3> waypoints    = new List <Vector3>();
        Vector2        directionOld = Vector2.zero;

        for (int i = 1; i < path.Count; i++)
        {
            Vector2 directionNew = new Vector2(path[i - 1].gridX - path[i].gridX, path[i - 1].gridY - path[i].gridY); //Gives us the direction from the previous node to the NEW one
            if (directionNew != directionOld)                                                                         //IF THE DIRECTION ISN'T THE SAME, IT ADDS IT
            {
                waypoints.Add(path[i - 1].worldPosition);
            }
            directionOld = directionNew;

            if (i == path.Count - 1 && directionOld != new Vector2(path[i].gridX, path[i].gridY) - new Vector2(startNode.gridX, startNode.gridY))             //Adds a neighbor node at the start of the path if needed
            {
                waypoints.Add(path[path.Count - 1].worldPosition);
            }
        }

        //waypoints.Add(path[path.Count-1].worldPosition); //This works! However, it will always add another node when the path refreshes.
        return(waypoints.ToArray());
    }