Clamping problem when the canvas is moved

Hello everyone,
I am making a placement script and when the canvas (plot) is in, y, 0) the clamp works perfectly, but when I move the canvas somewhere else, the clamp doesn’t work.

When the canvas is in the center:

When the canvas is not in the center:


function clampToBounds(canvas,model, position) 
	local lPos = canvas.CFrame:pointToObjectSpace(position)
	local modelPrimaryPart = model.PrimaryPart
	local sx, sz = canvas.Size.X, canvas.Size.Z
	local offset = position - canvas.Position
	local x = math.clamp(lPos.X, -sx/2, sx/2)
	local z = math.clamp(lPos.Z, -sz/2, sz/2)

function CalculatePosition()
	local mouse_x = math.floor((mouse.Hit.X / grid) + 0.5) * grid
	local mouse_y = official_y
	local mouse_z = math.floor((mouse.Hit.Z / grid) + 0.5) * grid
	if part then
		local pos = clampToBounds(game.Workspace.Canvas, model,, mouse_y, mouse_z))
		model:SetPrimaryPartCFrame(model.PrimaryPart.CFrame:Lerp(, speed))


Thanks for the Help!

On the lines where you actually perform the clamp, you dont seem to ever actually offset the position using “offset”, because that variable is literally never used after being created:

local x = math.clamp(lPos.X, -sx/2, sx/2)+offset.X
local z = math.clamp(lPos.Z, -sz/2, sz/2)+offset.Z

In the clampToBounds function, you are returning a global vector which doesn’t take into account the local position of the canvas, or “lPos” as you defined it.

Let’s say X = 5, Z = 10
So when you place the object, it will place it in the global world at coordinates (5, Y, 10). You need to account for the position of the actual canvas, so you would return the local vector. Return this instead inside of the clampToBounds function:

return canvas.CFrame:pointToObjectSpace(, official_y, z))

Sorry for the super late reply, Roblox Studio was giving me problems; unfortunately, both of your solutions did not solve the problem.