# Help with keeping parts' positions inside of a boundary

I’m making a building system and I’m having trouble keeping the builds inside of a boundary when the build is rotated. Here’s a video of my issue:

The boundary works fine when the build isn’t rotated but when I rotate it, it acts as if the build wasn’t rotated at all in terms of keeping the build inside of the boundary. I’m not really sure how I can approach the issue.

Here’s my code for keeping the build inside of the boundary:

``````local function clampToBoundaries(model)
model:SetPrimaryPartCFrame(CFrame.new(
math.clamp(model.PrimaryPart.Position.X, bounds.Position.X - bounds.Size.X/2 + model.PrimaryPart.Size.X/2, bounds.Position.X + bounds.Size.X/2 - model.PrimaryPart.Size.X/2),
model.PrimaryPart.Position.Y,
math.clamp(model.PrimaryPart.Position.Z, bounds.Position.Z - bounds.Size.Z/2 + model.PrimaryPart.Size.Z/2, bounds.Position.Z + bounds.Size.Z/2 - model.PrimaryPart.Size.Z/2)
) * CFrame.Angles(0,rot,0))
end
``````

model being the build that is being clamped to the boundary
bounds being the part that measures the boundary
rot being the rotation of the model

I made a function for keeping a part or model inside an area earlier. It goes through every corner of every part in the model and finds the longest distance of a corner of a part from the edge. Then it calculates a new cframe based on the longest distance. So if there were corners outside the area, the corner that was furthest away from the edge will be at the edge.
I have later realised that this code

``````for ix = 1, 2 do
local xm =(-1)^ix
for iy = 1, 2 do
local ym =(-1)^iy
for iz = 1, 2 do
local zm =(-1)^iz
``````

could be replaced with this

``````for xm = -1, 1, 2 do
for ym = -1, 1, 2 do
for zm = -1, 1, 2 do
``````

Edit: @ThanksRoBama 's code is a better idea for 90 degree rotations.

Does your design only need 90 degree rotations? If so, you can figure out the “world-space size” like so:

``````local function clampToBoundaries(model)
local modelSizeWorldSpace = model.CFrame:VectorToWorldSpace(model.PrimaryPart.Size)
model:SetPrimaryPartCFrame(CFrame.new(
math.clamp(model.PrimaryPart.Position.X, bounds.Position.X - bounds.Size.X/2 + modelSizeWorldSpace.X/2, bounds.Position.X + bounds.Size.X/2 - modelSizeWorldSpace.X/2),
model.PrimaryPart.Position.Y,
math.clamp(model.PrimaryPart.Position.Z, bounds.Position.Z - bounds.Size.Z/2 + modelSizeWorldSpace.Z/2, bounds.Position.Z + bounds.Size.Z/2 - modelSizeWorldSpace.Z/2)
) * CFrame.Angles(0,rot,0))
end
``````

That produces this:

It seems like it is rotating around a corner and that’s why it goes outside of the boundary. But I have made my own solution:

``````local XP
local XS
local ZP
local ZS

XP = model.PrimaryPart.Position.X
XS = model.PrimaryPart.Size.X
ZP = model.PrimaryPart.Position.Z
ZS = model.PrimaryPart.Size.Z
else
XP = model.PrimaryPart.Position.Z
XS = model.PrimaryPart.Size.Z
ZP = model.PrimaryPart.Position.X
ZS = model.PrimaryPart.Size.X
end

model:SetPrimaryPartCFrame(CFrame.new(
math.clamp(model.PrimaryPart.Position.X, (bounds.Position.X - bounds.Size.X/2) + XS/2, bounds.Position.X + bounds.Size.X/2 - XS/2),
model.PrimaryPart.Position.Y,
math.clamp(model.PrimaryPart.Position.Z, (bounds.Position.Z - bounds.Size.Z/2) + ZS/2, bounds.Position.Z + bounds.Size.Z/2 - ZS/2)
) * CFrame.Angles(0,rot,0))
``````

It basically just detects if the model is rotated and if it is switch the size axis around so the X becomes the Z and the Z becomes the X. This may not be the most efficient solution though so feel free to keep commenting.

1 Like