 # CFrame clamp on turret?

I have gone through every article I can find for the past couple of days trying to figure out how to limit the rotation of an object, yes I have looked at the other articles and I’m not wrapping my head around it.

Currently, I Have and many variants of this.

``````render.Heartbeat:Connect(function()
local mousePos = Mouse.Hit.Position
local rotate = Vector3.new(mousePos.X, turr.Position.Y, mousePos.Z)
turma:SetPrimaryPartCFrame(CFrame.new(turr.Position, rotate))
end)
``````

Looks like:

What id like to do is stop it from rotating over these red lines. Basically limiting its Y rotation to only a couple of degrees.
If you could point me in the right direction that would be wonderful.

1 Like

First you can set up a vector which would bisect your vision triangle.

Then you can use the dot product, to get the angle between the vector which represents the direction towards the mouse point, and the vector I described up there.

If the angle between these two vectors exceeds a value, then you can clamp it or do something with it as necessary

``````local bisectingVector = ...
local totalAngle = ...
render.Heartbeat:Connect(function()
local mousePos = Mouse.Hit.Position
local direction = (turr.Position - mousePos).unit
local angle = math.acos(direction:Dot(bisectingVector);
if angle > totalAngle * .5 then
-- clamp it here
end

local rotate = Vector3.new(mousePos.X, turr.Position.Y, mousePos.Z)
turma:SetPrimaryPartCFrame(CFrame.new(turr.Position, rotate))
end)
``````
2 Likes

Yo

If you want to know how it works here is the clamping function, I convert the CFrame to orientation then clamp the orientation angles.

Code sniplet
``````--Inverse the part0 only for Motor6D's
--Set it to CFrame.new() for non Motor6ds
local relativeToWorld = currentJointMotor6D.Part0.CFrame:Inverse()

local lookAtWorld = CFrame.lookAt(turretPosition,lookAtPosition,baseCFrame.UpVector)--goal LookAt CFrame

local goalCFrame

if self.Constraints then
local turretRelativeCF = baseCFrame:ToObjectSpace(lookAtWorld)
local x , y , z = turretRelativeCF:ToOrientation()
--print(math.deg(x),math.deg(y),math.deg(z))
local constrainedX , constrainedY = self:EulerClampXY(x,y)

local jointPosition = currentJointMotor6D.Part0.CFrame*originalC0Position
local _,y, _ = baseRelative:ToOrientation()
constrainedY = math.abs(constrainedY)*math.sign(y)--use the quadrants of the lookAtFromJoint

--print(math.deg(constrainedX),math.deg(constrainedY))
--print(math.deg(constrainedY))
goalCFrame = relativeToWorld*baseCFrame*CFrame.fromOrientation(constrainedX,constrainedY,z)*turretCFrameRotationOffset
else
--Unconstrained use lookAtWorld
goalCFrame = relativeToWorld*lookAtWorld*turretCFrameRotationOffset
end

--Euler Clamp function:
-- negative z is front, x is rightvector
function TurretController:EulerClampXY(x,y)
local Constraints =  self.Constraints
local degY = math.deg(y)
local degX = math.deg(x)
local newY = math.clamp(degY,-Constraints.YawRight,Constraints.YawLeft)
local newX = math.clamp(degX,-Constraints.DepressionAngle, Constraints.ElevationAngle)

end
``````

Edit: For your case do this,

``````render.Heartbeat:Connect(function()
local mousePos = Mouse.Hit.Position
local rotate = Vector3.new(mousePos.X, turr.Position.Y, mousePos.Z)
local goalCFrame = CFrame.new(turr.Position, rotate)
local x,y,z = goalCFrame:ToOrientation()
print(math.deg(x),math.deg(y),math.deg(z))
--Notice the angles being changed
--Then you can clamp the angles
turma:SetPrimaryPartCFrame(goalCFrame)
end)

``````
1 Like

Thank you, but honestly, I have no idea what any of that means. I’ll need to look into clamps.

So if im not mistaken clamping where you noted will limit how much it can rotate.
from my understanding, I can use math.clamp(y,-20,20) and it would only let me move it by 40 degrees.
so it would look something like
turma:SetPrimaryPartCFrame(goalCFrame,math.clamp(y,-20,20)) ?

Well, here is a more simpler code snippet:

``````render.Heartbeat:Connect(function()
local mousePos = Mouse.Hit.Position
local rotate = Vector3.new(mousePos.X, turr.Position.Y, mousePos.Z)
local goalCFrame = CFrame.new(turr.Position, rotate)
local x,y,z = goalCFrame:ToOrientation()
--print(math.deg(x),math.deg(y),math.deg(z))
--Notice the angles being changed
--Then you can clamp the angles, restrict it
--clamps between -30 to 30 degrees
clampedY = math.clamp(math.deg(y),-30,30)