Пример #1
0
        private static void GetAdjacentNodes(AStarGrid grid, AStarNode node, ref NativeArray <AStarNode> adjacentNodes, out int length)
        {
            length = 0;

            // +X
            if (!node.IsBlockedPosX)
            {
                int x = node.XCoord + 1;
                int y = node.YCoord;
                if (x < grid.LengthX && grid.HasNode(x, y) && grid[x, y].IsTraverseable && !grid[x, y].IsBlockedNegX)
                {
                    adjacentNodes[length++] = grid[x, y];
                }
            }
            // -X
            if (!node.IsBlockedNegX)
            {
                int x = node.XCoord - 1;
                int y = node.YCoord;
                if (x >= 0 && grid.HasNode(x, y) && grid[x, y].IsTraverseable && !grid[x, y].IsBlockedPosX)
                {
                    adjacentNodes[length++] = grid[x, y];
                }
            }
            // +Y
            if (!node.IsBlockedPosY)
            {
                int x = node.XCoord;
                int y = node.YCoord + 1;
                if (y < grid.LengthY && grid.HasNode(x, y) && grid[x, y].IsTraverseable && !grid[x, y].IsBlockedNegY)
                {
                    adjacentNodes[length++] = grid[x, y];
                }
            }
            // -Y
            if (!node.IsBlockedNegY)
            {
                int x = node.XCoord;
                int y = node.YCoord - 1;
                if (y >= 0 && grid.HasNode(x, y) && grid[x, y].IsTraverseable && !grid[x, y].IsBlockedPosY)
                {
                    adjacentNodes[length++] = grid[x, y];
                }
            }
        }
Пример #2
0
        public static bool SolvePath(AStarGrid grid, AStarNode start, AStarNode end, ref NativeList <AStarNode> pathNodes)
        {
            NativeList <AStarNode> openNodes   = new NativeList <AStarNode>(Allocator.Temp);
            NativeList <AStarNode> closedNodes = new NativeList <AStarNode>(Allocator.Temp);

            AStarNode current = start;

            openNodes.Add(start);

            bool pathFound = false;

            while (openNodes.Length > 0)
            {
                current = openNodes[0];
                int minF = current.F;
                for (int i = 1, n = openNodes.Length; i < n; i++)
                {
                    if (minF > openNodes[i].F)
                    {
                        current = openNodes[i];
                    }
                }

                closedNodes.Add(current);

                openNodes.RemoveAtSwapBack(openNodes.IndexOf(current));

                if (current.Equals(end))
                {
                    // Path to end found
                    pathFound = true;
                    break;
                }

                NativeArray <AStarNode> adjacentNodes = new NativeArray <AStarNode>(4, Allocator.Temp);
                int length = 0;
                GetAdjacentNodes(grid, current, ref adjacentNodes, out length);

                for (int i = 0; i < length; i++)
                {
                    AStarNode adjacent = adjacentNodes[i];

                    if (closedNodes.IndexOf(adjacent) < 0)
                    {
                        if (openNodes.IndexOf(adjacent) < 0)
                        {
                            adjacent.parentIndex = current.Index;
                            adjacent.G           = DistanceToNode(adjacent, end);
                            adjacent.H           = adjacent.TraversalCost + grid[adjacent.parentIndex].H;

                            openNodes.Add(adjacent);

                            grid[adjacent.XCoord, adjacent.YCoord] = adjacent;
                        }
                    }
                }

                adjacentNodes.Dispose();
            }

            if (pathFound)
            {
                while (current.parentIndex >= 0)
                {
                    pathNodes.Add(current);
                    current = grid[current.parentIndex];
                }
                pathNodes.Add(start);

                // Reverse
                for (int i = 0, i2 = pathNodes.Length - 1; i < i2; i++, i2--)
                {
                    AStarNode t = pathNodes[i];
                    pathNodes[i]  = pathNodes[i2];
                    pathNodes[i2] = t;
                }
            }

            openNodes.Dispose();
            closedNodes.Dispose();

            return(pathFound);
        }
Пример #3
0
            public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            {
                NativeArray <NavigationGridData>  navigationGrids    = chunk.GetNativeArray(this.navigationGridType);
                BufferAccessor <AStarNodeElement> nodeBufferAccessor = chunk.GetBufferAccessor(this.nodeBufferType);

                for (int ci = 0, cn = chunk.Count; ci < cn; ci++)
                {
                    NavigationGridData navigationGrid           = outNavigationGrid[0] = navigationGrids[ci];
                    DynamicBuffer <AStarNodeElement> nodeBuffer = nodeBufferAccessor[ci];

                    // Solve path if requested

                    if (navigationGrid.pathRequested)
                    {
                        // All nodes
                        NativeArray <AStarNode> nodes = nodeBuffer.Reinterpret <AStarNode>().ToNativeArray(Allocator.Temp);

                        // Create temp grid
                        AStarGrid aStarGrid = new AStarGrid(navigationGrid.lengthX, navigationGrid.lengthY, nodes);

                        // Start/end nodes
                        AStarNode start = navigationGrid.pathStart;
                        AStarNode end   = navigationGrid.pathEnd;

                        // Solve path
                        NativeList <AStarNode> pathNodeList = new NativeList <AStarNode>(Allocator.Temp);
                        bool pathFound  = AStarSolver.SolvePath(aStarGrid, start, end, ref pathNodeList);
                        int  pathLength = pathNodeList.Length;
                        if (pathFound && navigationGrid.pathMustBeStraightLine)
                        {
                            // Check if path is straight line if specfied as a requirement
                            bool xDiverge = false;
                            bool yDiverge = false;
                            for (int i = 1, n = pathNodeList.Length; i < n; i++)
                            {
                                if (!xDiverge)
                                {
                                    xDiverge = pathNodeList[i].XCoord != pathNodeList[i - 1].XCoord;
                                }
                                if (!yDiverge)
                                {
                                    yDiverge = pathNodeList[i].YCoord != pathNodeList[i - 1].YCoord;
                                }
                                if (xDiverge && yDiverge)
                                {
                                    pathFound = false;
                                    break;
                                }
                            }
                        }


                        // Copy path node list to output array
                        NativeSlice <AStarNode> pathNodeListSlice = new NativeSlice <AStarNode>(pathNodeList.AsArray());
                        NativeSlice <AStarNode> pathNodeSlice     = new NativeSlice <AStarNode>(this.outPathNodes, 0, pathLength);
                        pathNodeSlice.CopyFrom(pathNodeListSlice);

                        // Dispose native containers
                        pathNodeList.Dispose();
                        aStarGrid.Dispose();
                        nodes.Dispose();

                        this.outPathFound[0]                  = pathFound ? 1 : 0;
                        this.outPathFound[1]                  = pathLength;
                        navigationGrid.pathRequested          = false;
                        navigationGrid.pathMustBeStraightLine = false;

                        // Apply changes
                        navigationGrids[ci] = navigationGrid;
                    }
                }
            }