Trying to code the camera for a turret, where the players camera movement is limited. Currently the code I have clamps the camera but does it relative to the world direction instead of the turret direction
local rX, rY, rZ = Camera.CFrame:ToOrientation()
local limX = math.clamp(math.deg(rX), -45, 45)
local limY = math.clamp(math.deg(rY), -45, 45)
local clampedOrientation = CFrame.fromOrientation(math.rad(limX), math.rad(limY), rZ)
Camera.CFrame = CFrame.new(Camera.CFrame.p) * clampedOrientation
I tried changing it to be relative to its reference part (CamPart) but that just breaks it entirely:
local CamPart = Turret.CamPart -- Reference part for the cameras origin
local relativeCF = Camera.CFrame:ToObjectSpace(CFrame.lookAt(Camera.CFrame.Position, CamPart.CFrame.LookVector, CamPart.CFrame.UpVector))
local rX, rY, rZ = relativeCF:ToOrientation()
local limX = math.clamp(math.deg(rX), -45, 45)
local limY = math.clamp(math.deg(rY), -45, 45)
local clampedOrientation = CFrame.fromOrientation(math.rad(limX), math.rad(limY), rZ)
Camera.CFrame = CFrame.new(Camera.CFrame.p) * clampedOrientation
This is looped using RunService:BindToRenderStep("TurretControl",Enum.RenderPriority.Camera.Value + 1, controlLoop)
I have done this for my module which is on my profile.
It should look something like this:
local baseCFrame : CFrame
if turretBase:IsA("Attachment") then
baseCFrame = turretBase.WorldCFrame-turretBase.WorldCFrame.Position
else
baseCFrame = turretBase.CFrame-turretBase.CFrame.Position
end
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
goalCFrame = relativeToWorld*lookAtWorld*turretCFrameRotationOffset
end
The key is converting it relative to a baseCFrame, then comverting it back to world space
Im having some trouble implementing this, it just makes my camera act crazy:
heres my code:
local lookAtPosition = Camera.CFrame.LookVector
local jointPosition = Camera.CFrame.Position
local relativeToWorld = Camera.CFrame:Inverse()
local baseCFrame = CamPart.CFrame - CamPart.CFrame.Position
local lookAtWorld = CFrame.lookAt(CamPart.CFrame.Position,lookAtPosition,baseCFrame.UpVector)--goal LookAt CFrame
local relativeCF = baseCFrame:ToObjectSpace(lookAtWorld)
local rX , rY , rZ = relativeCF:ToOrientation()
local limX = math.clamp(math.deg(rX), -45, 45)
local limY = math.clamp(math.deg(rY), -45, 45)
local quadrantLookAtFromJointPosition = CFrame.lookAt(jointPosition,lookAtPosition,baseCFrame.UpVector)
local baseRelative = baseCFrame:ToObjectSpace(quadrantLookAtFromJointPosition)
local _,y, _ = baseRelative:ToOrientation()
rY = math.abs(rY)*math.sign(y)--use the quadrants of the lookAtFromJoint
Camera.CFrame = relativeToWorld*baseCFrame*CFrame.fromOrientation(limX,limY,rZ)
i assumed lookAtPosition and jointPosition would be for the rotating part and baseCFrame would be what the rotating parts movement is based on