BodyGyro not as responsive as expected

I have a turret that fires when it’s looking directly at a player and has the ability to fire. It works fine, however when the player’s moving the turret lags behind the player’s actual position a little bit, only firing periodically. Here’s a video of what’s happening:

https://streamable.com/n94kc0

You can see the turret lag behind me and stop firing when I start to move, then it continues firing when I stop moving.

This is the code that’s responsible for moving the turret, deciding whether it’s okay to fire, and firing the turret

while wait() do
	for i, plr in pairs(game.Players:GetPlayers()) do
		local char = plr.Character
		if char and char:FindFirstChild("Humanoid") and char:FindFirstChild("HumanoidRootPart") then
			if not charAttacking then 
				charAttacking = char 
			end
			if (script.Parent.Gyro.Position - char:FindFirstChild("HumanoidRootPart").Position).Magnitude < (script.Parent.Gyro.Position - charAttacking:FindFirstChild("HumanoidRootPart").Position).Magnitude then 
				charAttacking = char 
			end
		end
	end
	
	if charAttacking then
		if charAttacking.Humanoid.Health > 0 and (script.Parent.Gyro.Position - charAttacking.HumanoidRootPart.Position).magnitude < range then
			if (script.Parent.Gyro.Position - charAttacking.HumanoidRootPart.Position).magnitude < 50 then
				script.Parent.Gyro.BodyGyro.CFrame = CFrame.new(script.Parent.Gyro.Position,charAttacking.HumanoidRootPart.Position) --problematic section

				local result = workspace:Raycast(script.Parent.Gyro.Position, script.Parent.Gyro.CFrame.LookVector*50,rayparams)
				if result then
					
					if (result.Instance.Parent:FindFirstChildOfClass("Humanoid") or result.Instance.Parent.Parent:FindFirstChildOfClass("Humanoid")) and canfire == true then
						spawn(function()
							canfire = false
							script.Parent.Gyro.Shoot:Play()
							wait(shootdelay)
							canfire = true
						end)
					end
				end
			end
		elseif (script.Parent.Gyro.Position - charAttacking.HumanoidRootPart.Position).magnitude > range then
			script.Parent.Gyro.BodyGyro.CFrame = CFrame.Angles(0,0,0)
		end
	end
end

The turret is based off of constraints to give it more realism, so I’m not considering using CFrame or tweens. Any help would be appreciated, thanks.

Part of the issue–and granted it won’t be emphasized as much in Studio as it would be on a live server (assuming that this turret is being simulated server-side. If not, ignore this)–is the delay in physics replication between the player and the server.

Your best bet would either be to incorporate the velocity of the player into the calculations so that the turret can guess where the player is going to be before they get there or add a cone-shaped area in front of the turret where it can shoot that is narrow enough to look like the turret is still shooting directly at the player.

Obviously, also, you can tinker with the force parameters of the BodyGyro, but you may instead be able to get faster turn times by using an AlignOrientation with a reference point that updates every frame and tweaking the AlignOrientation’s parameters to something that feels fair.