Exemple #1
0
        private const int maxPathLength     = 1000; // nodes
        private static float getHcost(Nav2dNode node, Nav2dNode end)
        {
            var dx = Mathf.Abs(node.worldPos.x - end.worldPos.x);
            var dy = Mathf.Abs(node.worldPos.y - end.worldPos.y);

            return(NonDiagonalCost * (dx + dy) + (DiagonalCost - 2 * NonDiagonalCost) * Mathf.Min(dx, dy));
        }
Exemple #2
0
        private void CreateNavCell(Vector3Int gridPos)
        {
            var cellsize  = grid.cellSize.x;
            var center    = grid.GetCellCenterWorld(gridPos);
            var northWest = center + new Vector3(-cellsize / 2, -cellsize / 2, 0);


            // creating the nodes

            var nodeCenter = new Nav2dNode(center);
            // var nodeObjectCenter = Instantiate(node, nodeCenter.worldPos, Quaternion.identity, this.transform);
            // nodeObjectCenter.node = nodeCenter;

            var nodeNorthWest = new Nav2dNode(northWest);

            //var nodeObjectWest = Instantiate(node, nodeNorthWest.worldPos, Quaternion.identity, this.transform);
            //nodeObjectWest.node = nodeNorthWest;


            //setting nodes in cells

            nodes.Add(nodeCenter);
            nodes.Add(nodeNorthWest);

            var cell = cellsArray[new Vector2Int(gridPos.x, gridPos.y)] = new Nav2dCell(gridPos);

            cell.setNode(nodeCenter, new Vector2Int(0, 0));
            cell.setNode(nodeNorthWest, new Vector2Int(-1, -1));


            var leftCell = FindNavCellAtPosition(gridPos + new Vector3Int(-1, 0, 0));

            if (leftCell != null)
            {
                leftCell.setNode(nodeNorthWest, new Vector2Int(1, -1));
            }

            var downCell = FindNavCellAtPosition(gridPos + new Vector3Int(0, -1, 0));

            if (downCell != null)
            {
                downCell.setNode(nodeNorthWest, new Vector2Int(-1, 1));
            }

            var leftDownCell = FindNavCellAtPosition(gridPos + new Vector3Int(-1, -1, 0));

            if (leftDownCell != null)
            {
                leftDownCell.setNode(nodeNorthWest, new Vector2Int(1, 1));
            }


            //return cellsArray[gridPos.x, gridPos.y];
        }
Exemple #3
0
        private void CreateAdjacentNodesConnections(Nav2dCell cell)
        {
            var cells = new Dictionary <string, Nav2dCell> {
                { "leftDown", FindNavCellAtPosition(cell.gridPos + new Vector3Int(-1, -1, 0)) },
                { "leftTop", FindNavCellAtPosition(cell.gridPos + new Vector3Int(-1, 1, 0)) }, // left down
                { "left", FindNavCellAtPosition(cell.gridPos + new Vector3Int(-1, 0, 0)) },    // left
                { "top", FindNavCellAtPosition(cell.gridPos + new Vector3Int(0, 1, 0)) },      // top
                { "down", FindNavCellAtPosition(cell.gridPos + new Vector3Int(0, -1, 0)) },    // down
                { "right", FindNavCellAtPosition(cell.gridPos + new Vector3Int(1, 0, 0)) },
                { "rightTop", FindNavCellAtPosition(cell.gridPos + new Vector3Int(1, 1, 0)) },
                { "rightDown", FindNavCellAtPosition(cell.gridPos + new Vector3Int(1, -1, 0)) }
            };


            // table of nodes to test connection
            Nav2dNode[] centerNodeNeighbors = new Nav2dNode[9] {
                cell.getNode(-1, -1),
                cells["left"]?.getNode(0, 0),
                cells["top"]?.getNode(-1, -1),
                cells["down"]?.getNode(0, 0),
                null,
                cells["top"]?.getNode(0, 0),
                cells["right"]?.getNode(-1, -1),
                cells["right"]?.getNode(0, 0),
                cells["rightTop"]?.getNode(-1, -1)
            };

            //sets connection two ways

            cell.getNode(0, 0).setAccessibility(centerNodeNeighbors, LayerMask.GetMask(collisionLayers));

            Nav2dNode[] northWestNodeNeighbors = new Nav2dNode[9] {
                cells["leftDown"]?.getNode(0, 0),
                cells["left"]?.getNode(-1, -1),
                cells["left"]?.getNode(0, 0),
                cells["down"]?.getNode(-1, -1),
                null,
                cells["top"]?.getNode(-1, -1),
                cells["down"]?.getNode(0, 0),
                cells["right"]?.getNode(-1, -1),
                cell.getNode(0, 0)
            };

            //sets connection two ways
            cell.getNode(-1, -1).setAccessibility(northWestNodeNeighbors, LayerMask.GetMask(collisionLayers));
        }
Exemple #4
0
        public Nav2dNode findClosestAccessibleNodeInGrid(Vector3Int cellPos, Vector3 targetPos)
        {
            Nav2dNode node = null;

            C5.HashSet <Vector3Int> explored = new C5.HashSet <Vector3Int>();
            Queue <Vector3Int>      opened   = new Queue <Vector3Int>();

            opened.Enqueue(cellPos);

            // dont try to long
            for (int i = 0; i < 20; i++)
            {
                Vector3Int current = opened.Dequeue();
                Nav2dCell  cell    = FindNavCellAtPosition(current);

                node = cell?.findClosestAccessibleNodeInCell(targetPos);

                if (node != null)
                {
                    break;
                }

                explored.Add(current);

                Vector3Int[] neighbors =
                {
                    current + new Vector3Int(0,   1, 0),
                    current + new Vector3Int(0,  -1, 0),
                    current + new Vector3Int(-1,  0, 0),
                    current + new Vector3Int(1,   0, 0)
                };

                foreach (var n in neighbors)
                {
                    if (!explored.Contains(n))
                    {
                        opened.Enqueue(n);
                    }
                }
            }
            return(node);
        }
Exemple #5
0
 public void setNode(Nav2dNode node, Vector2Int direction)
 {
     nodes[direction.x + 1, direction.y + 1] = node;
 }
Exemple #6
0
        public static IEnumerable <Nav2dNode> findShortestPath(Nav2dNode start, Nav2dNode end, float determinationLevel)
        {
            System.Collections.Generic.IList <Nav2dNode> result = new List <Nav2dNode>();
            Nav2dNode current = null;


            if (start == null || end == null || !start.accessible || !end.accessible)
            {
                return(null);
            }


            var pCosts = new Dictionary <Nav2dNode, float>();
            var gCosts = new Dictionary <Nav2dNode, float>();
            var parent = new Dictionary <Nav2dNode, Nav2dNode>();
            var opened = new IntervalHeap <Nav2dNode>(new NodeCompare(pCosts), MemoryType.Normal);

            opened.Add(start);
            gCosts[start] = 0;
            pCosts[start] = getHcost(start, end);

            while (!opened.IsEmpty)
            {
                current = opened.DeleteMin();

                if (current == end)
                {
                    break;
                }

                foreach (var neighbor in current.getNeighbors())
                {
                    // add neighbor or not to the openedQueue.
                    if (neighbor.accessible)
                    {
                        float newCost;
                        float hCost;
                        lock (neighbor)
                        {
                            newCost = gCosts[current] + getGCost(current, neighbor);
                            hCost   = getHcost(neighbor, end);
                        }

                        if (!gCosts.ContainsKey(neighbor) || newCost < gCosts[neighbor])
                        {
                            gCosts[neighbor] = newCost;
                            pCosts[neighbor] = gCosts[neighbor] + hCost;

                            opened.Add(neighbor);
                            parent[neighbor] = current;
                        }
                    }
                }
            }

            do
            {
                result.Add(current);
            } while (parent.TryGetValue(current, out current) && result.Count < maxPathLength);


            // need to loop from start to stop path early depending on determination level
            if (determinationLevel != -1)
            {
                return(result.Reverse().TakeWhile(x =>
                                                  // add start cost so that AI is not stuck inside costly node
                                                  x.travelCost < start.travelCost + determinationLevel
                                                  ).Reverse());
            }

            return(result);
        }
Exemple #7
0
        private static float getGCost(Nav2dNode current, Nav2dNode next)
        {
            var normalized = (current.worldPos - next.worldPos).normalized;

            return(((normalized.x == 0 || normalized.y == 0) ? NonDiagonalCost : DiagonalCost) + next.travelCost);
        }