Automated Turret mischief

First off, the code:

Code
-- - - ///////// SERVICES ////////// - - --
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")

-- - - ///////// HIERARCHY ////////// - - --

-- > // Hierarchy //
local turret = script.Parent
local barrel = turret.Barrel.Barrels
local hinge = turret.TurretHinge
local SFXAttach = barrel.SFX
local VFXAttach = barrel.VFX
-- ///////////////// --

-- > // Sounds //
local spinSound = SFXAttach.Spin
local shootSound = SFXAttach.Shoot
local stopSound = SFXAttach.Stop
local deploySound = SFXAttach.Deploy
-- ///////////////// --

-- > // Visuals //
local particle = VFXAttach.Gunshot
local laser = barrel.Laser
local laserEndAttach = barrel.LaserEnd
-- ///////////////// --


-- - - ///////// CONFIGURATION ////////// - - --

local config = script.Configuration

local laserColor = config:GetAttribute("LaserColor")
local dmg = config:GetAttribute("Damage")
local accuracy = config:GetAttribute("Accuracy")
local deployRange = config:GetAttribute("DeployRange")
local turretEnabled = config:GetAttribute("Enabled")

-- - - ///////// CODE ////////// - - --

-- > // CODE VARS //
local isDeployed = false
local target = nil
local lastTargetHit = nil
-- ///////////////// --


-- > Function: Toggle deployment of the turret
local function ToggleDeploy(toggle: boolean)
	if toggle and not isDeployed then
		isDeployed = true
		laser.Color = laserColor
		laser.Enabled = true
		deploySound:Play()
	elseif not toggle and isDeployed then
		isDeployed = false
		laser.Enabled = false
	end
end

-- > Function: Check the area for players
local function CheckArea()
	local params = OverlapParams.new()
	params.FilterDescendantsInstances = {turret}
	params.FilterType = Enum.RaycastFilterType.Exclude

	local area = workspace:GetPartBoundsInRadius(hinge.Position, deployRange, params)
	local playerDetected = false

	for _, part in pairs(area) do
		local parentModel = part.Parent
		if part:IsA("BasePart") and parentModel and parentModel:FindFirstChild("Humanoid") then
			print("AHH PLAYER!!")
			playerDetected = true
			break
		end
	end

	ToggleDeploy(playerDetected)
end

-- > Function: Move barrel to random positions within a scanning range
local function MoveBarrel()
	if not isDeployed then
		return
	end

	local randomAngle = math.random(-30, 30)
	hinge.CFrame = hinge.CFrame * CFrame.Angles(math.rad(randomAngle), 0, 0)

	local rayOrigin = barrel.Position
	local rayDirection = VFXAttach.CFrame.LookVector * 500
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {turret}
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.IgnoreWater = true

	local rayResult = workspace:Raycast(rayOrigin, rayDirection, params)
	laserEndAttach.Position = rayResult.Position or rayResult.Instance.Position
	if rayResult then
		local hitPart = rayResult.Instance
		if hitPart.Parent:FindFirstChild("Humanoid") then
			print("Target acquired!")
			target = hitPart.Parent
		else
			print("No player hit.")
			target = nil
		end
	end
end

-- > Main update loop
RunService.Heartbeat:Connect(function()
	task.wait()
	if not turretEnabled then
		return
	end

	if isDeployed then
		MoveBarrel()
	else
		CheckArea()
	end
end)

The turret seems to do a whole lot of nothing (well not exactly nothing, it does do some stuff but it’s jank.

Here’s what I mean:

What could be causing it? Additionally, here’s the hierarchy:

Is there any script controlling the turret?
If not, then this is not scripting support, maybe building support