Snap to grid even if out of boundary

My code isn’t the same as @DataSigh

try this:

--you will need to know the grid size in worldspace position
local plot = workspace.plot
local plotSize = plot.Size

local gridsizeX = {
    plot.Position.X - plotSize.X / 2,
    plot.Position.X + plotSize.X / 2
}

local gridsizeZ = {
    plot.Position.Z - plotSize.Z / 2,
    plot.Position.Z + plotSize.Z / 2
}

RunService.Heartbeat:Connect(function(dt)
	if mouse.Target ==  nil then return end
	
	if mouse.Target.Parent.Parent.Name == "gridParts" then -- checks if its a grid part
		local pos = mouse.Hit
		
		TweenService:Create(selectionpart.PrimaryPart,TweenInfo.new(0.4,Enum.EasingStyle.Quad),
		{CFrame = pos * CFrame.Angles(0, math.rad(rotation), 0)}
		):Play()
	else
		--SECOND PART
		local pos = mouse.Hit

		--clamp the X/Z positions here and add the angle directly
		local cframeClampedPosition = CFrame.new(
			math.clamp(pos.X, gridsizeX[1], gridsizeX[2]),
			plot.Position.Y + selectionpart.PrimaryPart.Size.Y / 2,
			math.clamp(pos.Z, gridsizeZ[1], gridsizeZ[2])
		) * CFrame.Angles(0, math.rad(rotation), 0)

		TweenService:Create(selectionpart.PrimaryPart,TweenInfo.new(0.4,Enum.EasingStyle.Quad),
		{CFrame = cframeClampedPosition}
		):Play()
	end
end)
1 Like

Check if your rojo is connected

Okay, yeah with mouse.Hit it works

Its working properly but, if the cursor is pointing to the sky it doesn’t detect it

try this:

--you will need to know the grid size in worldspace position
local plot = workspace.plot
local plotSize = plot.Size

local gridsizeX = {
    plot.Position.X - plotSize.X / 2,
    plot.Position.X + plotSize.X / 2
}

local gridsizeZ = {
    plot.Position.Z - plotSize.Z / 2,
    plot.Position.Z + plotSize.Z / 2
}

RunService.Heartbeat:Connect(function(dt)
	if mouse.Target and mouse.Target.Parent.Parent.Name == "gridParts" then -- checks if its a grid part
		local pos = mouse.Hit
		
		TweenService:Create(selectionpart.PrimaryPart,TweenInfo.new(0.4,Enum.EasingStyle.Quad),
		{CFrame = pos * CFrame.Angles(0, math.rad(rotation), 0)}
		):Play()
	else
		--SECOND PART
		local pos = mouse.Hit

		--clamp the X/Z positions here and add the angle directly
		local cframeClampedPosition = CFrame.new(
			math.clamp(pos.X, gridsizeX[1], gridsizeX[2]),
			plot.Position.Y + selectionpart.PrimaryPart.Size.Y / 2,
			math.clamp(pos.Z, gridsizeZ[1], gridsizeZ[2])
		) * CFrame.Angles(0, math.rad(rotation), 0)

		TweenService:Create(selectionpart.PrimaryPart,TweenInfo.new(0.4,Enum.EasingStyle.Quad),
		{CFrame = cframeClampedPosition}
		):Play()
	end
end)
1 Like

Yeah that works good except the height when its out of bounds

Here is the updated code

RunService.Heartbeat:Connect(function(dt)
	if mouse.Target and mouse.Target.Parent.Parent.Name == "gridParts" then -- checks if its a grid part
		local pos = mouse.Target.CFrame

		TweenService:Create(selectionpart.PrimaryPart,TweenInfo.new(0.4,Enum.EasingStyle.Quad),
			{CFrame = pos * CFrame.Angles(0, math.rad(rotation), 0)}
		):Play()
	else
		--SECOND PART
		local pos = mouse.Hit

		--clamp the X/Z positions here and add the angle directly
		local cframeClampedPosition = CFrame.new(
			math.clamp(pos.X, gridsizeX[1], gridsizeX[2]),
			plot.Position.Y + selectionpart.PrimaryPart.Size.Y / 2, -- # object is a bit lower than usual for some reason
			math.clamp(pos.Z, gridsizeZ[1], gridsizeZ[2])
		) * CFrame.Angles(0, math.rad(rotation), 0)

		TweenService:Create(selectionpart.PrimaryPart,TweenInfo.new(0.4,Enum.EasingStyle.Quad),
			{CFrame = cframeClampedPosition}
		):Play()
	end
end)

I tried setting the Y just to plot.Position.Y but same result

plot.Position.Y + selectionpart.PrimaryPart.Size.Y / 2, -- # object is a bit lower than usual for some reason

1 Like

What about plot.Position.Y + plot.Size.Y / 2 + selectionpart.PrimaryPart.Size.Y / 2

2 Likes

Thank you! That works

Do you know what the logic will be behind making the object not go off grid?

image

local halfSizeX = selectionpart.PrimaryPart.Size.X / 2
local halfSizeZ = selectionpart.PrimaryPart.Size.Z / 2

local cframeClampedPosition = CFrame.new(
	math.clamp(pos.X, gridsizeX[1] + halfSizeX, gridsizeX[2] - halfSizeX),
	plot.Position.Y + plot.Size.Y / 2 + selectionpart.PrimaryPart.Size.Y / 2,
	math.clamp(pos.Z, gridsizeZ[1] + halfSizeZ, gridsizeZ[2] - halfSizeZ)
) * CFrame.Angles(0, math.rad(rotation), 0)
2 Likes

That works great vertically but not horizontally

image


image

1 Like

When you’re figuring out the bounds, add the selection parts size as a variable so it clamps from the edge of the selection part instead of the center

And that edge will be the back or front of the model?

yes, depending on where it’s being clamped, you add the size length of the model

Yes, but even when changing the size it doesnt account for 2 grids, am I doing something wrong?
image

(I can’t place to the right)

local halfSizeX
local halfSizeZ
if rotation == 0 or 180 then
	halfSizeX = selectionpart.PrimaryPart.Size.X / 2
	halfSizeZ = selectionpart.PrimaryPart.Size.Z / 2
elseif rotation == 90 or 270 then
	halfSizeX = selectionpart.PrimaryPart.Size.X
	halfSizeZ = selectionpart.PrimaryPart.Size.Z			
end
1 Like

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