Turret shoots in a wall while attempting to hit player

  1. What do you want to achieve? i want the turret to fire at the target only when it is in its field of view

  2. What is the issue? in the video

  3. What solutions have you tried so far? I didn’t find anything useful on devforum

game:GetService("RunService").Heartbeat:Connect(function()
	for _,v in pairs(workspace:GetChildren()) do
		if v:FindFirstChildOfClass("Humanoid") ~= nil then
			local character = v
			local torso = character:FindFirstChild("Torso")
			local humanoid = character:FindFirstChild("Humanoid")
			if torso and humanoid.Health > 0 then
				if (torso.Position - tool.TurretPart.Position).magnitude < MAX_DIST then
					local rand = math.random(1,6)
					if rand == 1 then
						target = character:FindFirstChild("Torso")
					elseif rand == 2 then
						target = character:FindFirstChild("Head")
					elseif rand == 3 then
						target = character:FindFirstChild("Left Arm")
					elseif rand == 4 then
						target = character:FindFirstChild("Right Arm")
					elseif rand == 5 then
						target = character:FindFirstChild("Left Leg")
					elseif rand == 6 then
						target = character:FindFirstChild("Right Leg")
					end
				else
					target = nil
				end
			end
		end
	end
	
	if target then
		firePoint.Light.Part.Color = Color3.fromRGB(0, 255, 0)
		firePoint.Light.Part.PointLight.Color = Color3.fromRGB(0, 255, 0)
		local torso = target
		firePoint = tool.TurretPart
		local target = {CFrame = CFrame.new(tool.TurretPart.Position, torso.Position)}
		--tool.TurretPart.CFrame = CFrame.new(tool.TurretPart.Position, torso.Position)
		local maked = tweenser:Create(tool.TurretPart,info,target)
		maked:Play()
	else
		firePoint.Light.Part.Color = Color3.fromRGB(255, 0, 0)
		firePoint.Light.Part.PointLight.Color = Color3.fromRGB(255, 0, 0)
	end
	wait(1)
end)

while wait(0.2) do
	if target ~= nil then
		local origin = firePoint.Position
		--local direction = firePoint.WorldCFrame.LookVector.Unit
		Fire(origin)
	end	
end

You need to do a raycast from head of the turret to player’s target instance.

First, prepare create parameters for the raycast, and add turret to blacklist

local ignoredObject = {turretModel}

local usedParams = RaycastParams.new()
usedParams.FilterType = Enum.RaycastFilterType.Blacklist
usedParams.FilterDescendantsInstances = ignoredObjects

Then, we create function that raycasts from the firePoint.Position to the target we selected.

local function CheckIfCanFire(target)
	local LookVector = CFrame.new(firePoint.Position, target.Position).LookVector
	local RaycastResult = workspace:Raycast(firePoint.Position, LookVector * 100)
	
	if RaycastResult then
		if RaycastResult.Instance == target then
			return true
		end
	end
end

Add this check before firing at the target

if CheckIfCanFire(target) then

I tried a lot to fix this problem with your function, but for some reason it did not work for me. By changing the script a little, I got some result, but it’s bad. Maybe if I post the full script it will be possible to find out what the problem is?

local tool = script.Parent
local tweenser = game:GetService("TweenService")
local info = TweenInfo.new(0.2,Enum.EasingStyle.Back)
--local firePoint = tool.TurretPart.FirePoint
local firePoint = tool.TurretPart
local pelletsFolder = workspace.debris
local repstorage = game:GetService("ReplicatedStorage")
local pellet = game:GetService("ServerStorage").Pellet
local bullethit = repstorage:WaitForChild("Remotes").BulletHit
local FastCast = require(repstorage:WaitForChild("Modules").FastCastRedux)
local PartCache = require(repstorage:WaitForChild("Modules").PartCache)
local soundmodule = require(repstorage:WaitForChild("Modules").SoundPlayerModule)

local damage = 5
local MAX_DIST = 35
local MIN_SPREAD = 1.5
local MAX_SPREAD = 3

local caster = FastCast.new()
local provider = PartCache.new(pellet, 100, pelletsFolder)

local castParams = RaycastParams.new()
castParams.FilterType = Enum.RaycastFilterType.Blacklist
castParams.FilterDescendantsInstances = {script.Parent,workspace.debris}

local target = nil
local behavior = FastCast.newBehavior()
behavior.CosmeticBulletProvider = provider
behavior.CosmeticBulletContainer = pelletsFolder
behavior.Acceleration = Vector3.new(0, -workspace.Gravity, 0)

game:GetService("RunService").Heartbeat:Connect(function()
	for _,v in pairs(workspace:GetChildren()) do
		if v:FindFirstChildOfClass("Humanoid") ~= nil then
			local character = v
			local humanoid = character:FindFirstChild("Humanoid")
			local targetpart = character:GetChildren()[math.random(#character:GetChildren())]
			if targetpart and targetpart:IsA("Part") then
				local LookVector = CFrame.new(firePoint.Position, targetpart.Position).LookVector
				local RaycastResult = workspace:Raycast(firePoint.Position, LookVector * 1000,castParams)
				if RaycastResult and humanoid.Health > 0 then
					if (targetpart.Position - tool.TurretPart.Position).magnitude < MAX_DIST and RaycastResult.Instance == targetpart then
						target = targetpart
						firePoint.Light.Part.Color = Color3.fromRGB(0, 255, 0)
						firePoint.Light.Part.PointLight.Color = Color3.fromRGB(0, 255, 0)
						local targets = {CFrame = CFrame.new(tool.TurretPart.Position, targetpart.Position)}
						local maked = tweenser:Create(tool.TurretPart,info,targets)
						maked:Play()
					else
						target = nil
						firePoint.Light.Part.Color = Color3.fromRGB(255, 0, 0)
						firePoint.Light.Part.PointLight.Color = Color3.fromRGB(255, 0, 0)
					end
				end
			end
		end
	end
end)

local function Fire(origin)
	soundmodule.PlaySound(repstorage.Sounds.TurretFire, firePoint)
	local direction = firePoint.CFrame.LookVector
	game.ServerScriptService.GunScriptsModels.Bullet:Invoke("Pellet",damage,1000,MIN_SPREAD,MAX_SPREAD,MAX_DIST,firePoint,game.Debris,firePoint.CFrame.LookVector * 100,{script.Parent},1,true)
end
--[[
caster.LengthChanged:Connect(function(cast, lastPoint, dir, displacment, segVel, pellet)
	pellet.CFrame = CFrame.lookAt(lastPoint + (dir * displacment), lastPoint)
end)
]]
tool.health:GetPropertyChangedSignal("Value"):Connect(function()
	if tool.health.Value <= 0 then
		Instance.new("Explosion", firePoint)
	end
end)

while wait(0.2) do
	if target ~= nil then
		local origin = firePoint.Position
		Fire(origin)
	end	
end

The issue was that raycast was hitting other parts of the player’s body. When turret selected random part of the body to shoot for, it often was blocked by some other part of the body.

Change from line 22 to line 59 in your script to this:

-- :: This table needs to be seperate for castParams updates

local castFilter = {script.Parent, workspace.debris}

local castParams = RaycastParams.new()
castParams.FilterType = Enum.RaycastFilterType.Blacklist
castParams.FilterDescendantsInstances = castFilter

local target = nil
local behavior = FastCast.newBehavior()
behavior.CosmeticBulletProvider = provider
behavior.CosmeticBulletContainer = pelletsFolder
behavior.Acceleration = Vector3.new(0, -workspace.Gravity, 0)

game:GetService("RunService").Heartbeat:Connect(function()
	for _,v in pairs(workspace:GetChildren()) do
		if v:FindFirstChildOfClass("Humanoid") then

			local character = v
			local humanoid = character:FindFirstChild("Humanoid")

			-- :: I changed from randomness to only HumanoidRootPart,
			-- :: it is the center of the body and always works.

			local HRP = character:FindFirstChild("HumanoidRootPart")
			local target = HRP

			if target and humanoid.Health > 0 then
				
				-- :: Before the casting, we need to add other character's part
				-- :: to filter for them not to block the ray.
				
				for i,v in pairs(character:GetChildren()) do
					if v ~= target and not table.find(castParams.FilterDescendantsInstances, v) then						
						table.insert(target, v)
						castParams.FilterDescendantsInstances = castFilter
					end
				end

				local LookVector = CFrame.new(firePoint.Position, target.Position).LookVector
				local RaycastResult = workspace:Raycast(firePoint.Position, LookVector * 1000,castParams)

				if RaycastResult  then
					if (target.Position - tool.TurretPart.Position).magnitude < MAX_DIST and RaycastResult.Instance == target then
						target = target
						firePoint.Light.Part.Color = Color3.fromRGB(0, 255, 0)
						firePoint.Light.Part.PointLight.Color = Color3.fromRGB(0, 255, 0)
						local targets = {CFrame = CFrame.new(tool.TurretPart.Position, target.Position)}
						local maked = tweenser:Create(tool.TurretPart,info,targets)
						maked:Play()
					else
						target = nil
						firePoint.Light.Part.Color = Color3.fromRGB(255, 0, 0)
						firePoint.Light.Part.PointLight.Color = Color3.fromRGB(255, 0, 0)
					end
				end
			end
		end
	end
end)

Have you checked if the part canquery is checked on.
Have you return or stop when it detects a part or anything that isnt humanoid, have you checked if it even detect the walls?