Clamp Motor6D C0 Rotation

Im using the code from this post to make part face the direction your mouse is pointing, using its motor6D. The problem is i dont know how to clamp it so it cant face downward.


function cframeObjectRotation(motor6DJoint,worldCFrame)
	local part1CF = motor6DJoint.Part1.CFrame
	local c1Store = motor6DJoint.C1
	local c0Store = motor6DJoint.C0
	local relativeToPart1 = c0Store*c1Store:Inverse()*part1CF:Inverse()*worldCFrame*c1Store

	local goalC0CFrame = relativeToPart1.Rotation+c0Store.Position--New orientation but keep old C0 joint position

	return goalC0CFrame

local TiltM6D = TiltBase:WaitForChild("TiltM6D")

	local unitRay = Camera:ViewportPointToRay(Mouse.X, Mouse.Y)
	local unitRayDir = unitRay.Direction * 10000

	-- Tilt
	local TiltDir =,unitRayDir.Y,unitRayDir.Z)
	local UDworldRotationCFrame =, TiltDir)
	local goalCF = cframeObjectRotation(TiltM6D, UDworldRotationCFrame)
	TiltM6D.C0 = goalCF

  1. Convert to object space relative to a “BasePart”
  2. Convert to orientation
  3. Clamp the orientation
  4. Convert orientation to CFrame
  5. Convert to world space relative to a “BasePart”

Example code from my turret controller:

	local relativeToWorld = currentJointMotor6D.Part0.CFrame:Inverse()

--Goal CFrame is in world space relative to origin(0,0,0)
	local lookAtWorld = CFrame.lookAt(turretPosition,lookAtPosition,baseCFrame.UpVector)--goal LookAt CFrame

	if self.Constraints then
--baseCFrame is another part for example the torso, used to measure if the lookAt is aiming 30 degrees above relative to the torso.
		local turretRelativeCF = baseCFrame:ToObjectSpace(lookAtWorld)
		local x , y , z = turretRelativeCF:ToOrientation()
		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
		goalCFrame = relativeToWorld*baseCFrame*CFrame.fromOrientation(constrainedX,constrainedY,z)*turretCFrameRotationOffset
		goalCFrame = relativeToWorld*lookAtWorld*turretCFrameRotationOffset