How to fix this issue with part snapping?

Hello, I’m trying to make my placement system snap to an increment of 1 stud, but when I do so, I get my block (which is 1x1x1) hovering .5 studs from the baseplate and I can only place my block onto another block my mouse is on the positive X,Y,Z value sides, otherwise, it places the block inside the other part.

GIF:
ezgif-4-d813d12fa5

Relevant Code:

RunService.RenderStepped:Connect(function()
	if PlacingObject == true then
		mouse.TargetFilter = PreviewObject
		if PreviewObject:FindFirstChild("MainPart") then
			
			local RoundedX = math.round(mouse.Hit.Position.X)
			local RoundedY = math.round(mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2)
			local RoundedZ = math.round(mouse.Hit.Position.Z)
			print("RoundedX: "..RoundedX.." | RoundedY: "..RoundedY.." | RoundedZ: "..RoundedZ)
			local ObjectCFrame = CFrame.new(RoundedX, RoundedY, RoundedZ)
			local ObjectAngles = CFrame.Angles(0, math.rad(RotationAmount), 0)
			
			PreviewObject:SetPrimaryPartCFrame(ObjectCFrame * ObjectAngles)
		end
	end
end)
1 Like

either remove the Position.Y rounding or make the plane coordinates be integers so there is no need to round

I don’t understand what you, mean. When I remove the rounding there is no longer any snapping, and I don’t know what you mean by:

1 Like

You need to remove the round only for the Y axis, since its snapping on natural numbers only.

Here is what i mean:

			local RoundedX = math.round(mouse.Hit.Position.X)
			local RoundedY = mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2
			local RoundedZ = math.round(mouse.Hit.Position.Z)

but you are better off aligning the plane to have real number as its Y axis since this as you said removes the snapping behavior on the axis

I got it to somewhat work by doing this:

RunService.RenderStepped:Connect(function()
	if PlacingObject == true then
		mouse.TargetFilter = PreviewObject
		if PreviewObject:FindFirstChild("MainPart") then
			local RoundedX = math.round(mouse.Hit.Position.X)
			local RoundedY = math.round(mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2)
			local RoundedZ = math.round(mouse.Hit.Position.Z)
			local X = mouse.Hit.Position.X
			local Y = mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2
			local Z = mouse.Hit.Position.Z
			print("RoundedX: "..RoundedX.." | RoundedY: "..RoundedY.." | RoundedZ: "..RoundedZ)
			print("NonRoundedX: "..X.." | NonRoundedY: "..Y.." | NonRoundedZ: "..Z)
			
			if mouse.Target:IsA("BasePart") then
				if mouse.Target.CFrame == PreviewObject.PrimaryPart.CFrame then
					print("SAME CFRAME!")
					
					if X == RoundedX - 0.5 then
						print("Yes - X")
						
						XToUse = math.round(mouse.Hit.Position.X - 1)
						YToUse = math.round(mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2)
						ZToUse = math.round(mouse.Hit.Position.Z)
						print("XToUse: "..XToUse.." | YToUse: "..YToUse.." | ZToUse: "..ZToUse)
					elseif Y == RoundedY then
						print("Yes - Y")
						
						XToUse = math.round(mouse.Hit.Position.X)
						YToUse = math.round((mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2) - 1)
						ZToUse = math.round(mouse.Hit.Position.Z)
						print("XToUse: "..XToUse.." | YToUse: "..YToUse.." | ZToUse: "..ZToUse)
					elseif Z == RoundedZ + 0.5 then
						print("Yes - Z")
						
						XToUse = math.round(mouse.Hit.Position.X)
						YToUse = math.round(mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2)
						ZToUse = math.round(mouse.Hit.Position.Z + 1)
						print("XToUse: "..XToUse.." | YToUse: "..YToUse.." | ZToUse: "..ZToUse)
					else
						print("No")
						
						XToUse = math.round(mouse.Hit.Position.X)
						YToUse = math.round(mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2)
						ZToUse = math.round(mouse.Hit.Position.Z)
						print("XToUse: "..XToUse.." | YToUse: "..YToUse.." | ZToUse: "..ZToUse)
					end
				else
					print("No")
					XToUse = math.round(mouse.Hit.Position.X)
					YToUse = math.round(mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2)
					ZToUse = math.round(mouse.Hit.Position.Z)
				end
			else
				print("No")
				XToUse = math.round(mouse.Hit.Position.X)
				YToUse = math.round(mouse.Hit.Position.Y + PreviewObject.PrimaryPart.Size.Y / 2)
				ZToUse = math.round(mouse.Hit.Position.Z)
			end
			
			print("XToUse: "..XToUse.." | YToUse: "..YToUse.." | ZToUse: "..ZToUse)
			
			local ObjectCFrame = CFrame.new(XToUse, YToUse, ZToUse)
			local ObjectAngles = CFrame.Angles(0, math.rad(RotationAmount), 0)
			
			PreviewObject:SetPrimaryPartCFrame(ObjectCFrame * ObjectAngles)
		end
	end
end)

The only problem I have now is this: (and of course it is still hovering above the baseplate)

The reason is that it keeps switching between failing and succeeding at the if mouse.Target.CFrame == PreviewObject.PrimaryPart.CFrame then if statement.

Fixed the if statement by changing it to this: if mouse.Target.CFrame == CFrame.new(RoundedX, RoundedY, RoundedZ) then from this: if mouse.Target.CFrame == PreviewObject.PrimaryPart.CFrame then

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.