Limiting rotation for a turret

Hello. I am making a turret that points at the player’s mouse, and I tried to limit the rotation on the Y-axis but doesn’t seem to work properly. Here is a video:

And here is my code:

RunService.Heartbeat:Connect(function(dt)
	local toAim = mouse.Hit.Position;
	local CF = CFrame.lookAt(turret.Position, Vector3.new(toAim.X, turret.Position.Y, toAim.Z));
	local X, Y, Z = CF:ToOrientation();
	Y = math.clamp(Y, -2, 2)
	turret.CFrame = CFrame.new(turret.Position)*CFrame.Angles(0, Y, 0)
end)

Thank you so much for reading! :slight_smile: Any help is appreciated.

Is the angle supposed to be between -2 degrees and 2 degrees or -2 radians and 2 radians? ToOrientation gives the angles in radians, so the limit should be in radians, too. You can use math.rad to convert degrees to radians.

It is supposed to be in radians.

Does this work? The 0 angle seems to be in the opposite direction than it’s supposed to.

turret.CFrame = CFrame.new(turret.Position)*CFrame.Angles(0, math.pi+Y, 0)
1 Like

Doesn’t seem to work as intended. Video:

Code:

RunService.Heartbeat:Connect(function(dt)
	local toAim = mouse.Hit.Position;
	local CF = CFrame.lookAt(turret.Position, Vector3.new(toAim.X, turret.Position.Y, toAim.Z));
	local X, Y, Z = CF:ToOrientation();
	Y = math.clamp(Y, -2, 2)
	turret.CFrame = CFrame.new(turret.Position)*CFrame.Angles(0, math.pi+Y, 0)
end)

Is the rotation of the character supposed to affect this?

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local plr = Players.LocalPlayer

RunService.Heartbeat:Connect(function(dt)
	local toAim = mouse.Hit.Position

	local hrpCf = plr.Character.HumanoidRootPart.CFrame
	local hrpDir = hrpCf.LookVector
	local hrpDirX, hrpDirZ = hrpDir.X, hrpDir.Z

	local targetPos = toAim.Position
	local targetDirX, targetDirZ = targetPos.X-hrpCf.X, targetPos.Z-hrpCf.Z

	local hrpAngle, targetAngle = math.atan2(hrpDirX, -hrpDirZ), math.atan2(targetDirX, -targetDirZ)
	local y = hrpAngle+math.clamp(targetAngle-hrpAngle, -2, 2)
	turret.CFrame = CFrame.new(turret.Position)*CFrame.Angles(0, y, 0)
end)
1 Like

Thank you so much for writing that! But, the rotation of the character isn’t supposed to affect this. I tried this too but it didn’t work. Here’s a video:

Download studio tweaks, and make sure the turret part has the face looking at the correct direction in the barrel of the turret or else things might get weird.

image

Otherwise I believe in the original code the turret is clamped in the Global axis and not by how it was originally facing. I will take some code bits from my turret controller module to try apply it to your situation.

local baseCFrame = turret.CFrame -- the new XYZ axis of the turret CFrame, it's original orientation.
RunService.Heartbeat:Connect(function(dt)
	local toAim = mouse.Hit.Position;
	local CF = CFrame.lookAt(turret.Position, Vector3.new(toAim.X, turret.Position.Y, toAim.Z));
--math from my module
		local turretRelativeCF =baseCFrame :ToObjectSpace(CF)
		local _, Y , _ = turretRelativeCF:ToOrientation()
	Y = math.clamp(Y, -2, 2)
		local goalCFrame = baseCFrame*CFrame.fromOrientation(0,Y,0)
local rotationOnly = goalCFrame - goalCFrame.Position
	turret.CFrame = CFrame.new(turret.Position)*rotationOnly 
end)
1 Like

It works, but the only problem now I have is that when you’re going off the limits, it’s doing some weird thing, I don’t know how to explain, but you can see it in this video: