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.
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)
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)
--Detect quadrant of lookAt position
local jointPosition = currentJointMotor6D.Part0.CFrame*originalC0Position
local quadrantLookAtFromJointPosition = CFrame.lookAt(jointPosition,lookAtPosition,baseCFrame.UpVector)
local baseRelative = baseCFrame:ToObjectSpace(quadrantLookAtFromJointPosition)
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)
return math.rad(newX), math.rad(newY)
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)
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)) ?
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)
--convert back to radian
clampedY = math.rad(clampedY)
--Create new clamped goalCFrame, using clamped angles
local clampedGoalCFrame = CFrame.fromOrientation(x,clampedY,z)+turr.Position--maintain the turret position so add it
--use the new clamped CFrame
turma:SetPrimaryPartCFrame(clampedGoalCFrame)
end)