Snapping to grid relatively?

Snapping to global grid is simple enough but I’m trying to make it so I can also build on unanchored stuff by using the part I’m hovering on as a reference to my grid and I’m struggling with that

This is what I have so far for global grid placement

local Results = Root.Mouse.Cast(nil, CastParams)
if Results then
	local Pos = Results.Position
	local Normal = Results.Normal
	BuildCF = CFrame.new(
		(math.floor((Pos.X) / 2) * 2 + (Normal.X >= 0 and 1 or -1)),
		(math.floor((Pos.Y) / 2) * 2 + (Normal.Y >= 0 and 1 or -1)),
		(math.floor((Pos.Z) / 2) * 2 + (Normal.Z >= 0 and 1 or -1))
	)
	AttachTo = Results.Instance
end

Built blocks are welded to the AttachTo variable so I already got that figured out.

For more context this is how it looks when building on the ground (Global Grid)
image

but if I want to build on something unanchored / moving it is still trying to use the global grid. I want it to figure out a new grid relative to the what I’m hovering on
image

build pls wa brbrbrbr.rbxl (60.5 KB)
Here is the place for even more context if you need

the local building module is in starter pack > build > input module

You would have to find the CFrame (with Orientation) of the selected base Part and calculate from that item rather than Global Workspace.

That’s what I tried doing but something is wrong and I can’t figure out what

HeartbeatConnection = RS.Heartbeat:Connect(function()
	local Results = Root.Mouse.Cast(nil, CastParams)
	if Results then
		local Pos = Results.Position
		local Normal = Results.Normal

		local SnapPoint = (Results.Instance.CFrame - Results.Instance.Size/2):PointToObjectSpace(Pos)
		print(SnapPoint, Pos)
		SnapPoint = Vector3.new(
			(math.floor((SnapPoint.X) / 2) * 2) + (Normal.X >= 0 and 1 or -1),
			(math.floor((SnapPoint.Y) / 2) * 2) + (Normal.Y >= 0 and 1 or -1),
			(math.floor((SnapPoint.Z) / 2) * 2) + (Normal.Z >= 0 and 1 or -1)
		)
		BuildCF = Results.Instance.CFrame * CFrame.new(SnapPoint)
		AttachTo = Results.Instance

		Highlight.CFrame = Highlight.CFrame:Lerp(BuildCF, 0.5)
	end
end)

image

Have you tried using lookvector, upvector, and rightvector and also mouse.TargetSurface? pair them together whilst changing orientation should work.

1 Like

btw the file you sent has a confusing building system. Do you mind telling me how to operate it without completely breaking it? (lol)

right now a main issue with the solution i tried is if you try to build on the baseplate it just builds under it

that might explain why you can’t figure out how to build

@TheFortex try this. It should work. The way I made my block placement system is also like that, jus.t you cant place on the baseplate :confused:

This is the closest I could get to the desired results

HeartbeatConnection = RS.Heartbeat:Connect(function()
	local Results = Root.Mouse.Cast(nil, CastParams)
	if Results then
		local Pos = Results.Position
		local Normal = Results.Normal
		
		SnappedOffset = (Results.Instance.CFrame - Results.Instance.Size/2):PointToObjectSpace(Pos)
		SnappedOffset = CFrame.new(
			(math.floor((SnappedOffset.X) / 2) * 2) + (Normal.X >= 0 and 1 or -1),
			(math.floor((SnappedOffset.Y) / 2) * 2) + (Normal.Y >= 0 and 1 or -1),
			(math.floor((SnappedOffset.Z) / 2) * 2) + (Normal.Z >= 0 and 1 or -1)
		)
		AttachTo = Results.Instance

		Highlight.CFrame = Highlight.CFrame:Lerp((Results.Instance.CFrame - Results.Instance.Size/2) * SnappedOffset, 0.5)
	end
end)

Things work out great until the assembly I’m building on moves a little and the grid becomes off for some reason.

image

here’s the updated place in case you want to test for your own build pls wa brbrbrbr.rbxl (60.5 KB)

Local script is in starter pack > build > input module
Server script is in server script service > server > building

This won’t work because I plan to have more schematics that won’t be just a plain block. For example a door or a seat.

But try doing it for the orientation thing. It should work with that.