public OutdoorNode SidewalkEdgeNodeFromWorldPoint(Vector3 worldPosition)
    {
        if (grid == null)
        {
            Start();
        }
        float percentX = ((worldPosition.x - plane.transform.position.x) + gridWorldSize.x / 2) / gridWorldSize.x;
        float percentY = ((worldPosition.z - plane.transform.position.z) + gridWorldSize.y / 2) / gridWorldSize.y;

        percentX = Mathf.Clamp01(percentX);
        percentY = Mathf.Clamp01(percentY);
        int x = Mathf.RoundToInt((gridSizeX - 1) * percentX);
        int y = Mathf.RoundToInt((gridSizeY - 1) * percentY);

        if (grid [x, y].sidewalkEmptyEdge)
        {
            try
            {
                return(grid [x, y]);
            }
            catch (NullReferenceException)
            {
                Start();
                return(grid [x, y]);
            }
        }
        else
        {         // Find the nearest sidewalk edge node
            List <OutdoorNode> potentialEdgeNodes = new List <OutdoorNode>();
            foreach (OutdoorNode node in GetCrossSection(6, grid[x, y]))
            {
                if (node.sidewalkEmptyEdge)
                {
                    potentialEdgeNodes.Add(node);
                }
            }
            if (potentialEdgeNodes.Count == 1)
            {
                return(potentialEdgeNodes [0]);
            }
            else if (potentialEdgeNodes.Count > 1)
            {
                float       distance = 100;
                OutdoorNode toReturn = potentialEdgeNodes [0];
                foreach (OutdoorNode node in potentialEdgeNodes)
                {
                    float newDistance = Vector3.Distance(node.worldPosition, grid [x, y].worldPosition);
                    if (newDistance < distance)
                    {
                        distance = newDistance;
                        toReturn = node;
                    }
                }
                return(toReturn);
            }
        }
        return(new OutdoorNode());
    }
 public void GetOutdoorPath(Vector3 pos)
 {
     if (outdoorGrid == null)
     {
         outdoorGrid = GameObject.Find("OutdoorPlane").GetComponent <OutdoorGrid>();
     }
     outdoorTargetNode = outdoorGrid.NodeFromWorldPoint(pos);
     OutdoorPathRequestManager.RequestPath(transform.position, pos, OnOutdoorPathFound);
 }
Example #3
0
    int GetDistance(OutdoorNode nodeA, OutdoorNode 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));
    }
Example #4
0
    Vector3[] RetracePath(OutdoorNode startNode, OutdoorNode endNode)
    {
        List <OutdoorNode> path        = new List <OutdoorNode>();
        OutdoorNode        currentNode = endNode;

        while (currentNode != startNode)
        {
            path.Add(currentNode);
            currentNode = currentNode.parent;
        }
        Vector3[] waypoints = SimplifyPath(path);
        Array.Reverse(waypoints);
        return(waypoints);
    }
    public OutdoorNode GetClosestWalkableNode(OutdoorNode toCheck, int distance, Vector3 seekerPos, Vector3 targetPos)
    // Gets the closest walkable node from an unwalkable one.  If a target is generated that is unwalkable, this will allow the customer to generate a path to the closest node available to it
    // distance of 1 creates 3x3 node grid centered around the unwalkable node
    // 2 creates 5x5, etc
    {
        print("GetClosestWalkable");
        List <OutdoorNode> neighbours = new List <OutdoorNode>();
        OutdoorNode        lowest     = new OutdoorNode();

        for (int x = -distance; x <= distance; x++)
        {
            for (int y = -distance; y <= distance; y++)
            {
                if (x == 0 && y == 0)
                {
                    continue;
                }

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

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

        List <OutdoorNode> walkableCloseNeighbours = new List <OutdoorNode> ();

        if (neighbours.Count > 0)
        {
            // get closest node
        }
        else if (neighbours.Count == 0)
        {
            if (!(distance++ > 5))
            {
                return(GetClosestWalkableNode(toCheck, distance++, seekerPos, targetPos));
            }
        }
        return(lowest);
    }
    public List <OutdoorNode> GetCrossSection(int units, OutdoorNode node)
    {
        List <OutdoorNode> neighbours = new List <OutdoorNode> ();

        for (int x = -units; x <= units; x++)
        {
            for (int y = -units; y <= units; y++)
            {
                if (x == 0 && y == 0)
                {
                    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);
    }
    public void CreateGrid()
    {
        OutdoorNode[,] lastGrid = new OutdoorNode[gridSizeX, gridSizeY];
        bool lastGridExists = false;

        try
        {
            for (int i = 0; i < gridSizeX; i++)
            {
                for (int j = 0; j < gridSizeY; j++)
                {
                    OutdoorNode refNode = grid[i, j];
                    lastGrid [i, j] = new OutdoorNode(refNode.empty, refNode.walkable, refNode.drivable, refNode.crosswalk, refNode.buildable, refNode.movementPenalty, refNode.worldPosition, i, j);
                    lastGridExists  = true;
                }
            }
        }
        catch (Exception ex)
        {
            // print (ex);
            // Just wait till next time the method calls
        }
        grid = new OutdoorNode[gridSizeX, gridSizeY];
        Vector3            worldBottomLeft = transform.position - Vector3.right * gridWorldSize.x / 2 - Vector3.forward * gridWorldSize.y / 2;
        List <OutdoorNode> buildableNodes  = new List <OutdoorNode> ();

        foreach (GameObject plane in buildablePlanes)
        {
            Destroy(plane.gameObject);
        }
        buildablePlanes.Clear();
        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);
                bool    walkable        = (Physics.CheckSphere(worldPoint, nodeRadius, sidewalkMask));
                bool    drivable        = (Physics.CheckSphere(worldPoint, nodeRadius, roadMask));
                bool    crosswalk       = (Physics.CheckSphere(worldPoint, nodeRadius, crosswalkMask));
                bool    buildable       = (Physics.CheckSphere(worldPoint, nodeRadius, buildableMask));
                int     movementPenalty = 0;
                if (drivable && !crosswalk)
                {
                    movementPenalty = 2000;
                }
                else if (drivable && crosswalk)
                {
                    movementPenalty = 5;
                }
                else if (walkable)
                {
                    movementPenalty = 0;
                }
                else if (buildable)
                {
                    movementPenalty = 25;
                }
                bool empty = false;
                if (!Physics.CheckSphere(worldPoint, nodeRadius))
                {
                    empty           = true;
                    movementPenalty = 75;
                }
                grid [x, y] = new OutdoorNode(empty, walkable, drivable, crosswalk, buildable, movementPenalty, worldPoint, x, y);
                if (buildable)
                {
                    OutdoorNode toAdd = grid [x, y];
                    buildableNodes.Add(toAdd);
                }
            }
        }

        // ---------------------------------------------------
        //			Build the visible buildable zone
        // ---------------------------------------------------
        Vector2 bottomLeft = GetBottomLeft();

        foreach (OutdoorNode oNode in buildableNodes)
        {
            GameObject newPlane = Instantiate(dm.gridPlanePrefab);
            newPlane.name  = "BuildableZone";
            newPlane.tag   = "BuildableZone";
            newPlane.layer = 15;
            newPlane.GetComponent <MeshRenderer> ().material = outdoorDefaultTileTexture;
            newPlane.AddComponent <OutdoorNodePlane> ();
            newPlane.GetComponent <OutdoorNodePlane> ().gridX = grid [oNode.gridX, oNode.gridY].gridX;
            newPlane.GetComponent <OutdoorNodePlane> ().gridY = grid [oNode.gridX, oNode.gridY].gridY;
            newPlane.transform.localScale = new Vector3(nodeDiameter / 10, .1f, nodeDiameter / 10);
            OutdoorNode refNode = GetNodeFromGridIndex(oNode.gridX, oNode.gridY);
            grid [refNode.gridX, refNode.gridY].buildable = true;
            Vector3 planeLocation = grid [oNode.gridX, oNode.gridY].worldPosition;
            newPlane.transform.position    = new Vector3(planeLocation.x, storeBoundariesPlane.transform.position.y, planeLocation.z);
            newPlane.transform.eulerAngles = new Vector3(0, 0, 0);
            newPlane.transform.parent      = storeBoundariesPlane.transform;
            buildablePlanes.Add(newPlane);
        }
        // ---------------------------------------------------
        CheckWalkable();
    }
 public OutdoorNode GetNodeFromReference(OutdoorNode ref_)
 {
     return(grid [ref_.gridX, ref_.gridY]);
 }
    int distanceFromBuildableZone = 12; // Max amount of nodes to be expanded per use
    public int CreateEmptyGridPlanes()
    {                                   // returns the distance that is being expanded
        // Creates planes for the empty nodes surrounding the buildable zone (not every single empty node) w/ a distance of distanceFromBuildableZone
        //int gridXMax = (int) dm.buildableDimensions.x;
        //int gridZMax = (int) dm.buildableDimensions.y;
        Vector2 buildableBottomLeft = Vector2.zero;         // This will be the gridX and gridY of the node that is the bottom left of the buildable zone
        float   xPos = 100;
        float   zPos = -100;

        foreach (GameObject FloorTile in buildablePlanes)
        {
            // the bottom left node is the lowest x value and highest z value of the edgenodes
            if (FloorTile.transform.position.x < xPos)
            {
                buildableBottomLeft.x = FloorTile.GetComponent <OutdoorNodePlane> ().gridX;
                xPos = FloorTile.transform.position.x;
            }
            if (FloorTile.transform.position.z > zPos)
            {
                buildableBottomLeft.y = FloorTile.GetComponent <OutdoorNodePlane> ().gridY;
                zPos = FloorTile.transform.position.z;
            }
        }
        foreach (OutdoorNode node in grid)
        {
            if (node.buildable)
            {
                if (node.gridY == grid[(int)buildableBottomLeft.x, (int)buildableBottomLeft.y].gridY)
                {
                    for (int i = 0; i < distanceFromBuildableZone; i++)
                    {
                        GameObject newPlane = Instantiate(dm.gridPlanePrefab);
                        newPlane.name = "ExpandableNode";
                        newPlane.tag  = "ExpandableZ";
                        newPlane.GetComponent <MeshRenderer> ().material = greenOutdoorNode_Transparent;
                        OutdoorNode expandableNodeRef = GetNodeFromGridIndex(node.gridX, node.gridY + (i + 1));                        // Z direction
                        newPlane.AddComponent <OutdoorNodePlane>().gridX  = expandableNodeRef.gridX;
                        newPlane.GetComponent <OutdoorNodePlane> ().gridY = expandableNodeRef.gridY;
                        newPlane.transform.localScale = new Vector3(nodeDiameter / 10, .1f, nodeDiameter / 10);
                        Vector3 planeLocation = expandableNodeRef.worldPosition;
                        newPlane.transform.position = new Vector3(planeLocation.x, storeBoundariesPlane.transform.position.y, planeLocation.z);
                        tempEmptyPlanes.Add(newPlane);
                    }
                }
                OutdoorNode refNode = GetNodeFromGridIndex((int)(buildableBottomLeft.x + dm.buildableDimensions.x + 1), (int)buildableBottomLeft.y);
                if (node.gridX == refNode.gridX)
                {
                    for (int i = 0; i < distanceFromBuildableZone; i++)
                    {
                        GameObject newPlane = Instantiate(dm.gridPlanePrefab);
                        newPlane.name = "ExpandableNode";
                        newPlane.tag  = "ExpandableX";
                        newPlane.GetComponent <MeshRenderer> ().material = greenOutdoorNode_Transparent;
                        OutdoorNode expandableNodeRef = GetNodeFromGridIndex(node.gridX + (i + 2), node.gridY);                        // X direction
                        newPlane.AddComponent <OutdoorNodePlane> ().gridX = expandableNodeRef.gridX;
                        newPlane.GetComponent <OutdoorNodePlane> ().gridY = expandableNodeRef.gridY;
                        newPlane.transform.localScale = new Vector3(nodeDiameter / 10, .1f, nodeDiameter / 10);
                        Vector3 planeLocation = expandableNodeRef.worldPosition;
                        newPlane.transform.position = new Vector3(planeLocation.x, storeBoundariesPlane.transform.position.y, planeLocation.z);
                        tempEmptyPlanes.Add(newPlane);
                    }
                }
            }
        }
        return(distanceFromBuildableZone);
    }
Example #10
0
    IEnumerator FindPath(Vector3 startPos, Vector3 targetPos)
    {
        Vector3[] waypoints   = new Vector3[0];
        bool      pathSuccess = false;

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


        if (true)
        {
            Heap <OutdoorNode>    openSet   = new Heap <OutdoorNode>(grid.MaxSize);
            HashSet <OutdoorNode> closedSet = new HashSet <OutdoorNode>();
            openSet.Add(startNode);

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

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

                foreach (OutdoorNode neighbour in grid.GetNeighbours(currentNode))
                {
                    int extraMovementPenalty = 0;
                    foreach (OutdoorNode neighbour_ in grid.GetNeighbours(neighbour))
                    {
                        if (neighbour_.drivable || neighbour_.empty)
                        {
                            extraMovementPenalty = 10;
                        }
                    }
                    if (closedSet.Contains(neighbour))
                    {
                        continue;
                    }

                    int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) + neighbour.movementPenalty + extraMovementPenalty;
                    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, targetPos, pathSuccess);
    }