Today I come to you seeking math assistance. Long story short, I am allowing players in my game to use Handles to move certain objects. BUT - I need for the object they’re dragging to never be more than Y studs away from the ‘center’, which is PartX in this case.
I’m using the code below, which works fine for now. But it has no way of stopping players from dragging an object beyond a my desired range Y from PartX. I figure it has something to do with .magnitude, but I have no idea here.
I appreciate any and all responses!
handle_Z.MouseDrag:Connect(function(face, distance)
local adornee = handle_Z.Adornee
local direction = 1
if face == Enum.NormalId.Left then
direction = -1
end
adornee.CFrame = adornee.OriginalCFrame.Value * CFrame.new(distance * direction, 0, 0)
end)
I think you could use math.clamp for this. Only problem is that the boundary would be quadratic, not spherical. I haven’t really dabbled in adornments yet but I think something like this should work:
local maxDistance = 10
local partX = workspace.Part
-- inside of your MouseDrag connection
local partPosX = partX.Position.X
adornee.CFrame = adornee.OriginalCFrame.Value * CFrame.new(distance * direction, 0, 0)
local clampedPos = math.clamp(adornee.Position.X, partPosX - 10, partPosX + 10)
adornee.Position = Vector3.new(clampedPos, adornee.Position.Y, adornee.Position.Z)
Oh sweet! Thanks for the response. Unfortunately, this doesn’t seem to successfully clamp the part inside the quadratic range box. I’m able to drag the part beyond the range
Good catch! I’m not sure how I missed that. Oddly enough, the issue still persists after fixing it.
local adornee = module.gui.Handle_Z.Adornee
local direction = 1
if face == Enum.NormalId.Left then
direction = -1
end
local pos = adornee.Position.Z
adornee.CFrame = adornee.OriginalCFrame.Value * CFrame.new(distance * direction, 0, 0)
local clampedPos = math.clamp(adornee.Position.Z, pos - 3, pos + 3)
adornee.Position = Vector3.new(adornee.Position.X, adornee.Position.Y, clampedPos)
*I’m assuming I modified this correctly, though I could be wrong
Alrighty, I took a look and I am not sure what is going on. Might be due to the type of handle adornments you are using, if what I am going to write doesn’t help, could you provide the type of adornment you are using?
I wrote this up quickly (and very poorly), it generally moves in the same direction if using right, top or back but it’s a bit weird when using the other 3 axes but note the part doesn’t move past the clamp.
local handles = script.Parent.Handles
local initPart = workspace.InitPart
local maxDistance = 10
handles.Adornee = workspace.MovePart
handles.MouseDrag:Connect(function(normal, distance)
if normal == Enum.NormalId.Right or normal == Enum.NormalId.Left then -- right is X axis
local adornee = handles.Adornee
adornee.CFrame *= CFrame.new(distance,0,0)
local clamped = math.clamp(adornee.Position.X, initPart.Position.X - 10, initPart.Position.X + 10)
if normal == Enum.NormalId.Left then -- invert the distance to be consistent with the mouse's direction
clamped *= -1
end
adornee.Position = Vector3.new(clamped,adornee.Position.Y, adornee.Position.Z)
elseif normal == Enum.NormalId.Top or normal == Enum.NormalId.Bottom then -- top is Y axis
local adornee = handles.Adornee
adornee.CFrame *= CFrame.new(0,distance,0)
local clamped = math.clamp(adornee.Position.Y, initPart.Position.Y - 10, initPart.Position.Y + 10)
if normal == Enum.NormalId.Bottom then
clamped *= -1
end
adornee.Position = Vector3.new(adornee.Position.X,clamped,adornee.Position.Z)
elseif normal == Enum.NormalId.Back or normal == Enum.NormalId.Front then -- back is Z axis
local adornee = handles.Adornee
adornee.CFrame *= CFrame.new(0,0,distance)
local clamped = math.clamp(adornee.Position.Z, initPart.Position.Z - 10, initPart.Position.Z + 10)
if normal == Enum.NormalId.Front then
clamped *= -1
end
adornee.Position = Vector3.new(adornee.Position.X,adornee.Position.Y, clamped)
end
end)
Hey there, was able to get it working reliably, try this out:
local handles = script.Parent.Handles
local initPart = workspace.InitPart
local maxDistance = 10
handles.Adornee = workspace.MovePart
handles.MouseButton1Down:Connect(function()
local connections = {}
local adornee = handles.Adornee
local posOnDown = adornee.Position
connections[#connections + 1] = handles.MouseDrag:Connect(function(normal, distance)
if normal == Enum.NormalId.Right or normal == Enum.NormalId.Left then -- right is X axis
local tempPos = posOnDown + Vector3.new(distance,0,0)
local relativeX = initPart.Position.X - tempPos.X
if normal == Enum.NormalId.Right then
relativeX = -relativeX
end
local clamped = math.clamp(relativeX, -maxDistance, maxDistance)
adornee.Position = Vector3.new(initPart.Position.X + clamped, adornee.Position.Y, adornee.Position.Z)
elseif normal == Enum.NormalId.Top or normal == Enum.NormalId.Bottom then -- top is Y axis
local tempPos = posOnDown + Vector3.new(0,distance,0)
local relativeY = initPart.Position.Y - tempPos.Y
if normal == Enum.NormalId.Top then
relativeY = -relativeY
end
local clamped = math.clamp(relativeY, -maxDistance, maxDistance)
adornee.Position = Vector3.new(adornee.Position.X, initPart.Position.Y + clamped, adornee.Position.Z)
elseif normal == Enum.NormalId.Back or normal == Enum.NormalId.Front then -- back is Z axis
local tempPos = posOnDown + Vector3.new(0,0,distance)
local relativeZ = initPart.Position.Z - tempPos.Z
if normal == Enum.NormalId.Back then
relativeZ = -relativeZ
end
local clamped = math.clamp(relativeZ, -maxDistance, maxDistance)
adornee.Position = Vector3.new(adornee.Position.X, adornee.Position.Y, initPart.Position.Z + clamped)
end
end)
connections[#connections + 1] = handles.MouseButton1Up:Connect(function()
for i,v in pairs(connections) do
v:Disconnect()
end
end)
end)
It should work with rotated parts as it’s only updating the position, not the CFrame.
Whether it’s going to move along the axis it’s rotated on though, probably not. You’d probably have to use the Up/Right/LookVector to determine where to move the part.