Custom Grid System not working properly

https://playcanvas.com/project/1143050/overview/2d-pixel-clicker-game
In this project for the "Box clicker " scene I am making a pixel grid generator(in 3D).
How it works:

  • There are two scripts that are root of the problem, ‘GridGenerator.js’ and ‘GridClickHandler.js’.
  • The grid generator is attached to a plane. It takes in the area of the plane and calculates the size and position of each cell in the grid in accordance with specified rows and columns. This script stores the grid in a an object containing size of each cell and position. KEEP IN MIND THAT THE GRID IS A CALCULATED OBJECT NOT AN ENTITY.
  • The grid clicker handler casts a ray form the screen on mouse click and sees if the ray intersects with any cell from the grid if so then it will display a plane on screen and make sure that plane has the same size as cell.

The grid generates just fine however the Grid click handler does not respond accurately. Almost each time the grid is clicked the spawned box entity is somewhere else then the desired cell also sometimes a cell is clicked if the mouse is clicked just slightly outside the grid. I think the problem may be in the Grid clicker handler script’s isRayInCell() function.

var GridClickHandler = pc.createScript('gridClickHandler');

GridClickHandler.attributes.add('gridGeneratorEntity', {
    type: 'entity',
    title: 'Grid Generator Entity',
    description: 'Drag and drop the entity with the GridGenerator script here.'
});

GridClickHandler.attributes.add('boxPrefab', {
    type: 'entity',
    title: 'Box Prefab',
    description: 'Drag and drop the entity prefab for the box to spawn.'
});

GridClickHandler.prototype.initialize = function () {
    if (!this.gridGeneratorEntity || !this.gridGeneratorEntity.script || !this.gridGeneratorEntity.script.gridGenerator) {
        console.error('Grid Generator Entity not assigned or does not have the GridGenerator script.');
        return;
    }

    this.gridGenerator = this.gridGeneratorEntity.script.gridGenerator;
    this.occupiedPositions = {}; // Dictionary to keep track of occupied positions

    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this);
};

GridClickHandler.prototype.onMouseDown = function (event) {
    if (event.button === pc.MOUSEBUTTON_LEFT) {
        var pickPosition = this.pickGridPosition(event);
        if (pickPosition) {

            if (!this.isPositionOccupied(pickPosition)) {
                console.log("Clicked cell = " + pickPosition);
                this.spawnBoxEntity(pickPosition);
                this.markPositionAsOccupied(pickPosition);
            } 
            else {
                console.log("Position already occupied.");
            }
        }
    }
};

GridClickHandler.prototype.pickGridPosition = function (event) {
    var cameraEntity = this.app.root.findByName('Camera'); // Replace with your camera entity name
    if (!cameraEntity) {
        console.error('Camera entity not found.');
        return null;
    }

    var camera = cameraEntity.camera;

    var from = camera.screenToWorld(event.x, event.y, camera.nearClip);
    var to = camera.screenToWorld(event.x, event.y, camera.farClip);

    var ray = new pc.Ray(from, to.sub(from).normalize());

    // Iterate through the grid positions and check for intersections with the ray
    for (var cellKey in this.gridGenerator.grid) {
        var gridInfo = this.gridGenerator.grid[cellKey];
        var position = gridInfo.position;
        var cellSize = gridInfo.size;

        if (this.isRayInCell(ray, position, cellSize)) {
            return position;
        }
    }

    return null; // No intersection with grid
};

GridClickHandler.prototype.isPositionOccupied = function (position) {
    // Check if the position is already occupied
    return this.occupiedPositions[position.toString()] !== undefined;
};

GridClickHandler.prototype.markPositionAsOccupied = function (position) {
    // Mark the position as occupied
    this.occupiedPositions[position.toString()] = true;
};

GridClickHandler.prototype.isRayInCell = function (ray, cellPosition, cellSize) {
    // Calculate the minimum and maximum bounds of the cell
    var min = cellPosition.clone().sub(cellSize);
    var max = cellPosition.clone().add(cellSize);

    // Calculate the intersection point of the ray with the cell's bounding box
    var tMin = (min.x - ray.origin.x) / ray.direction.x;
    var tMax = (max.x - ray.origin.x) / ray.direction.x;

    if (tMin > tMax) {
        var temp = tMin;
        tMin = tMax;
        tMax = temp;
    }

    var tyMin = (min.y - ray.origin.y) / ray.direction.y;
    var tyMax = (max.y - ray.origin.y) / ray.direction.y;

    if (tyMin > tyMax) {
        var temp = tyMin;
        tyMin = tyMax;
        tyMax = temp;
    }

    if ((tMin > tyMax) || (tyMin > tMax)) {
        return false;
    }

    if (tyMin > tMin) {
        tMin = tyMin;
    }

    if (tyMax < tMax) {
        tMax = tyMax;
    }

    var tzMin = (min.z - ray.origin.z) / ray.direction.z;
    var tzMax = (max.z - ray.origin.z) / ray.direction.z;

    if (tzMin > tzMax) {
        var temp = tzMin;
        tzMin = tzMax;
        tzMax = temp;
    }

    if ((tMin > tzMax) || (tzMin > tMax)) {
        return false;
    }

    return true;
};

GridClickHandler.prototype.spawnBoxEntity = function (position) {
    if (!this.boxPrefab) {
        console.error('Box Prefab not assigned.');
        return;
    }

    var cellSize = this.gridGenerator.grid['cell_0_0'].size; // Get the size of the first cell (assuming all cells have the same size)

    var boxEntity = this.boxPrefab.clone();

    PictureManager.Instance.findPictureToEnable(boxEntity);

    boxEntity.setPosition(position);
    boxEntity.setLocalScale(cellSize); // Set the box size to match the cell size
    this.app.root.addChild(boxEntity);
    console.log("Box spawned at: " + boxEntity.getPosition());
};
var GridGenerator = pc.createScript('gridGenerator');

GridGenerator.attributes.add('rows', {
    type: 'number',
    default: 5,
    title: 'Rows'
});

GridGenerator.attributes.add('columns', {
    type: 'number',
    default: 5,
    title: 'Columns'
});


GridGenerator.prototype.initialize = function () {
    this.grid = {}; // Object to store cell locations and their 3D positions
    this.generateGrid();
};

GridGenerator.prototype.generateGrid = function () {
    var planeEntity = this.entity;

    // Get the size of the plane
    var planeSize = planeEntity.getLocalScale();

    // Calculate the step size for rows and columns
    var rowStep = planeSize.z / this.rows;
    var colStep = planeSize.x / this.columns;

    var cellSize = new pc.Vec3(colStep, rowStep, 1); // Size of each cell

    for (var i = 0; i < this.rows; i++) {
        for (var j = 0; j < this.columns; j++) {
            // Calculate the 3D position of the center of each grid cell
            var position = new pc.Vec3(
                -planeSize.x / 2 + j * colStep + colStep / 2,
                -planeSize.z / 2 + i * rowStep + rowStep / 2,
                0 // You can adjust the Z position if needed
            );

            // Store the 3D position and size in the grid object using cell coordinates as the key
            var cellKey = 'cell_' + i + '_' + j;
            this.grid[cellKey] = {
                position: position,
                size: cellSize
            };      
        }
    }
    // Log the grid object for reference
    console.log(this.grid);
};