Okay, so basically I’m working on a grid placement game but the clamping is wrong for anything that’s not 4x4.
For 4x4 objects (which is just the base, which is just the selection box thing), it’s all fine and dandy.
Basically, I’ve devised a little system that makes the offset of the x or z direction of the clamp that turns on if the baseplate has an odd position, like -1, 17.
Have a look.
However, as soon as I use a 2x8 base object, things start getting a bit weird.
As you can see here, the position clamping for the 2x8 is a bit off, and I'm quite unsure what to do. local rs = game.ReplicatedStorage local localplayer = game.Players.LocalPlayer local rotation = 0 local roundmodule = require(rs.ModuleScripts.Round) game:GetService("UserInputService").InputBegan:Connect(function(input) if input.KeyCode == Enum.KeyCode.R then if rotation>=4 then rotation = 0 else rotation = rotation+1 end end end) game:GetService("RunService").RenderStepped:Connect(function() if script.Parent.Build.Value==true then if not game.Workspace.Temp:FindFirstChild(script.Parent.Obj.Value) then rs[script.Parent.Type.Value][script.Parent.Obj.Value]:Clone().Parent = game.Workspace.Temp else localplayer:GetMouse().TargetFilter = game.Workspace.Temp[script.Parent.Obj.Value] local xesggo = 0 local zesggo = 0 local xer = 0 local zer = 0 if (rotation%2==0) then xer = game.Workspace.Temp[script.Parent.Obj.Value].PrimaryPart.Size.X zer = game.Workspace.Temp[script.Parent.Obj.Value].PrimaryPart.Size.Z else xer = game.Workspace.Temp[script.Parent.Obj.Value].PrimaryPart.Size.Z zer = game.Workspace.Temp[script.Parent.Obj.Value].PrimaryPart.Size.X end local xes = math.clamp(localplayer:GetMouse().Hit.p.X,game.Workspace.Grounds.Position.X-game.Workspace.Grounds.Size.X/2+xer/2,game.Workspace.Grounds.Position.X+game.Workspace.Grounds.Size.X/2-xer/2) local zes = math.clamp(localplayer:GetMouse().Hit.p.Z,game.Workspace.Grounds.Position.Z-game.Workspace.Grounds.Size.Z/2+zer/2,game.Workspace.Grounds.Position.Z+game.Workspace.Grounds.Size.Z/2-zer/2) if not (game.Workspace.Grounds.Position.X % 2 == 0) then xesggo = -1 end if not (game.Workspace.Grounds.Position.Z % 2 == 0) then zesggo = -1 end print(xesggo) print(zesggo) local cf = CFrame.new(roundmodule.round(xes,2)+xesggo,game.Workspace.Grounds.Position.Y+game.Workspace.Grounds.Size.Y/2+game.Workspace.Temp[script.Parent.Obj.Value].PrimaryPart.Size.Y/2,roundmodule.round(zes,2)+zesggo) * CFrame.fromEulerAnglesXYZ(0, math.rad(rotation*90), 0) game.Workspace.Temp[script.Parent.Obj.Value]:SetPrimaryPartCFrame(cf) end else localplayer:GetMouse().TargetFilter = nil end end)
Here is my placement code, which is a localscript, and the only script involved in the placement system. The round function derives from a module, and the function works as rounding the first argument to the second argument, which simplified is just the first argument is the number to be rounded, and the second argument is the interval at which the first argument is to be to.