I am working on a placement system that has been working great overall, however, the snapping system only works on intended on some objects.

I am trying to make objects snap every 1 stud. It does snap but it is sometimes off by 0.5 studs relative to the plot.

This is how it appears on the grid, another objects I have sits perfectly on each stud while this wall has been giving me issues.

This is the code for snapping:

```
function PlacementValidator.SnapToGrid(pos, objectSize, plotPos)
local GRID_SIZE = 1
return Vector3.new(
(pos.X // GRID_SIZE),
plotPos.Y + 0.5,
(pos.Z // GRID_SIZE)
)
end
```

which is then used here:

```
local cast = castMouse() --raycast function
if cast and cast.Position then
local size = self.Preview:GetExtentsSize()
local plotPos = self.Plot.PrimaryPart:GetPivot()
local snappedPosition = PlacementValidators.SnapToGrid(cast.Position, size, plotPos)
local cf = CFrame.new(snappedPosition) * CFrame.Angles(0, self.Rotation, 0)
self.Preview:PivotTo(cf)
```

I have seen other posts on snapping but I could not figure out how to implement in my system, it seems like such a simple fix but I am missing something. Thanks for any help!

Edit: I also see that this only happens for sizes that are odd numbers. When a size is an even number like 2 or 8 it works fine but 1 and 5 and such are offset by 0.5.

2 Likes

Try using math.floor on the SnapToGrid function:

```
function PlacementValidator.SnapToGrid(pos, objectSize, plotPos)
local GRID_SIZE = 1
local snappedX = math.floor(pos.X / GRID_SIZE + 0.5) * GRID_SIZE
local snappedY = plotPos.Y + 0.5
local snappedZ = math.floor(pos.Z / GRID_SIZE + 0.5) * GRID_SIZE
return Vector3.new(
snappedX,
snappedY,
snappedZ
)
end
```

2 Likes

Still gives me the same issues cause I used the double divide symbol `pos.x // GRID_SIZE`

to do math.floor (I’ve heard that works as an option?)

Maybe try factoring in objectSize

```
function PlacementValidator.SnapToGrid(pos, objectSize, plotPos)
local GRID_SIZE = 1
local halfGridSize = GRID_SIZE / 2
local halfObjectSizeX = objectSize.X / 2
local halfObjectSizeZ = objectSize.Z / 2
local snappedX = (pos.X - halfObjectSizeX + halfGridSize) // GRID_SIZE * GRID_SIZE + halfObjectSizeX
local snappedZ = (pos.Z - halfObjectSizeZ + halfGridSize) // GRID_SIZE * GRID_SIZE + halfObjectSizeZ
return Vector3.new(
snappedX,
plotPos.Y + 0.5,
snappedZ
)
end
```

2 Likes

It’s close, on one orientation it works but when I rotate it 90 degrees in game then it becomes offset again.

2 Likes

Found a workaround for this method. If the object has an odd number size on let’s say the x axis, then you just edit the pivot on the actual model so that it is not in the middle of an odd number (which caused it to be offset by 0.5; if the pivot is in the middle of 1 stud then it will snap to the middle of that 1 stud which is 0.5)

Hopefully this makes sense its a little hard to explain lol, just edit the pivot

2 Likes