Unfortunatly you're right. `grid_metrics` is designed in a way that it looks in the global environment and suffers of a lack of flexibility. Thus your code cannot work. This version works:


    # Main package function
    get_layer_counts <- function(las, res = 10) 
    {
      stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
      lidR:::as.raster.lasmetrics(stats)
    }
    
    # Metrics function to count points within height intervals
    layer_count_metrics <- function(Z, breaks) 
    {
      zcat <- findInterval(Z, breaks, left.open = TRUE)
      tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
      names(tcount) <- paste0("layer", 1:length(breaks))
      tcount
    }
    
    library(lidR)
    
    LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
    las = readLAS(LASfile)
    
    stats = get_layer_counts(las)

But you can notice one important drawback. You can't propagate the argument `breaks` through the `get_layer_count` function. I hope to fix that in the next release.

Also notice that I added `factor` before `table`. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.