Hey, I’m currently working on a game that requires a placement system which is locked to a grid of 3 studs, but I’m facing a very annoying issue that I have not been able to fix. The issue is that if I point my mouse on the side of another block, it clips into that block, while what I want it to do, is pivot to the position (on the grid) next to that block, on the side that my mouse is (sorry for the bad explanation, I don’t know how to say it.)
local rep = game:GetService("ReplicatedStorage")
local selectionBox = rep.Modules.PlacingSystems.SelectionBox
-- grid
local GRID_SIZE = 3
function module.Place(plr, item)
if not (plr and item) then return end
local itemFolder = rep.Items.InventoryItems:FindFirstChild(item)
local placeable = itemFolder.Information.Placeable.Value
if not placeable then return end
local model = itemFolder.Model:FindFirstChildWhichIsA("Model")
if not (model and model.PrimaryPart) then return end
local mouse = plr:GetMouse()
local ghost = model:Clone()
ghost.Parent = workspace
for i, part in pairs(ghost:GetDescendants()) do
if part:IsA("BasePart") then
part.Transparency = 0.5
part.CanCollide = false
end
end
mouse.TargetFilter = ghost
mouse.Move:Connect(function()
local MousePos = mouse.Hit.Position
local BlockPos = MousePos
BlockPos = BlockPos + Vector3.new(0, model.PrimaryPart.Size.Y / 2, 0)
local XPos = math.round(BlockPos.X / GRID_SIZE) * GRID_SIZE
local ZPos = math.round(BlockPos.Z / GRID_SIZE) * GRID_SIZE
BlockPos = Vector3.new(XPos, BlockPos.Y, ZPos)
ghost:PivotTo(CFrame.new(BlockPos))
end)
end
return module
I’m talking about the transparent part clipping by the way. I have not been able to make it place the block yet, because I want to fix this issue first
This is largely a matter of preference when building a system like that. Many go with it so you can integrate it into builds. A more common approach is to allow movement freely but prevent placement where objects would clip into other parts. Usually, with this approach, the object turns red to show it cannot be placed there. I prefer this method, with the object visually snapping into place, because it lets you move the build item freely while constructing, and the more you add to a build, the more convenient this becomes. You may want to reconsider your direction here.
This solution works for blocks that do not have a rotation, but a more generalized solution would be using RaycastResult.Normal (multiplied by some very small value, like you did with 0.1, but it can be much smaller like 10^-6). This is used to offset the position of the mouse (RaycastResult.Position + RaycastResult.Normal*(10^-6)) slightly, so that, instead of being perfectly in between two grid positions, it goes into the adjacent grid position
However, using the normal can only be done when using local RaycastResult = workspace:Raycast(...), as the Mouse object doesn’t provide the normal of the hit surface. For more information, you can look at this solution from another thread
I noticed your grid is set to 3. One simple approach to these build systems is to have your placed objects, like walls, be twice the length of the grid size and to avoid using an odd number for the grid itself. Clipping issues don’t automatically occur when you move a wall next to other walls, and the overall math works out nicely in even chunks, whether whole or split. A grid size of 4 is a good choice for many reasons. A wall with an 8-stud length moves right into place with the existing math, with no modifications needed.
Timing favors 3s, building favors 4s.
(naturally complements computational harmony)