So I got a block placement system but one problem is that you can place a block inside a block.
local function canPlaceBlocks()
local characterPrimary = character.PrimaryPart
local rayOrigin = characterPrimary.Position
local snapValue = 3 -- Grid size
local rayDirection = (characterPrimary.CFrame.LookVector - characterPrimary.CFrame.UpVector * placeBlockAngle).Unit * 8
local raycastResult = workspace:Raycast(rayOrigin, rayDirection)
if raycastResult then
local hitPosition = raycastResult.Position
local snapPosition = Vector3.new(
math.floor(hitPosition.X / snapValue + 0.5) * snapValue,
math.floor(hitPosition.Y / snapValue + 0.5) * snapValue,
math.floor(hitPosition.Z / snapValue + 0.5) * snapValue
)
placeBlock(snapPosition)
end
end