Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to fix my raycasting system for my turret?

Hi, I wanted to ask how to make a raycasting system for my turret 'cause I tried to create one but it never seemed to work. I know how the new raycasting functions work, but I don't know how to use them in a way so the turret will work! By the way, I tried to make the turret by attempting to rescript the raycasting used in this video:

local RS = game:GetService("ReplicatedStorage")
local bullet = RS:WaitForChild("Bullet")

local Turret = script.Parent

local fireRate = 1


local Damage = 20
local bulletSpeed = 250
local detectDistance = 50

while wait(fireRate) do

	
	
	local target = nil
	for i, v in pairs(game.Workspace:GetChildren()) do
		local human = v:FindFirstChild("Humanoid")
		local torso = v:FindFirstChild("Torso")
		if human and torso and human.Health > 0 then
			if (torso.Position - Turret.Position).magnitude <= detectDistance then
				local raycastParams = RaycastParams.new()
				raycastParams.FilterDescendantsInstances = {workspace.Turret}
				raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
				
				local BulletPathResult = 
			    workspace:Raycast(Turret.Position,(torso.Position - Turret.Position).Unit*detectDistance, raycastParams)
				
				-- Problem begins here
				if BulletPathResult.Instance == torso then
					print("Targeting the humanoid")
				else 
					print("Object is in the way")
				end
				--problem ends here
			end
		end
		
		if target then
			local torso = target
			
			Turret.CFrame = CFrame.new(Turret.Position, torso.Position)
			
			wait(fireRate)
			local bulletClone = bullet:Clone()
			bulletClone.Parent = game.Workspace
			bulletClone.Position = Turret.Position
			
			bulletClone.Velocity = Turret.CFrame.LookVector * bulletSpeed
			
			bulletClone.Touched:Connect(function(hit)
				local human = hit.Parent:FindFirstChild("Humanoid")
				if human then
					human:TakeDamage(Damage)
				end
				
				wait(3)
				bulletClone:Destroy()
			end)
		end
	end
end

1 answer

✓ Accepted answer

Kinda sounds like your targeting code is getting confused with things in the workspace.

try this code:

local RS = game:GetService("ReplicatedStorage")
local bullet = RS:WaitForChild("Bullet")

local Turret = script.Parent

local fireRate = 1


local Damage = 20
local bulletSpeed = 250
local detectDistance = 50

--// new function for handling the targeting code. This simply finds the Closest humanoid in the workspace
function getHumanoidTarget()
	local target = nil
	local Dist = detectDistance 
	for k,v in pairs(workspace:GetChildren()) do -- replace workspace:GetChildren() with workspace:GetDescendants() for a more full but slow search 
		local Humanoid = v:FindFirstChildOfClass("Humanoid")
		local Torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if(Humanoid ~= nil and Humanoid.Health > 0 and Torso ~= nil) then
			local dist = (Torso.Position - Turret.Position).magnitude
			if(dist < Dist) then
				Dist = dist
				target = v
			end
		end
	end
	return target
end

while wait(fireRate) do
	
	local target = nil
	local tgt = getHumanoidTarget() -- Call our new Targeting function
	if(tgt ~= nil) then -- we've got a target!
		local torso = tgt:FindFirstChild("Torso") or tgt:FindFirstChild("HumanoidRootPart")
		if(torso ~= nil) then -- It has a torso or HumanoidRootPart!
		if (torso.Position - Turret.Position).magnitude <= detectDistance then -- woot we can see it!
			local raycastParams = RaycastParams.new()
			raycastParams.FilterDescendantsInstances = {workspace.Turret}
			raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

			local BulletPathResult = workspace:Raycast(Turret.Position,(torso.Position - Turret.Position).Unit*detectDistance, raycastParams)

			-- Problem begins here -- should be fixed!
				if BulletPathResult.Instance == torso 
					or BulletPathResult.Instance.Parent:FindFirstChild(torso.Name) then -- remove this bit to make it less precise in targeting 
				print("Targeting the humanoid")
					target = torso
			else 
				target = nil
				print("Object is in the way")
			end
			--problem ends here
		end
		end
		if target then
			local torso = target

			Turret.CFrame = CFrame.new(Turret.Position, torso.Position)
			
			print("Fire")
			local bulletClone = bullet:Clone()
			bulletClone.Parent = game.Workspace
			bulletClone.Position = Turret.Position
			bulletClone.Velocity = Turret.CFrame.LookVector * bulletSpeed
			bulletClone.Touched:Connect(function(hit)
				local human = hit.Parent:FindFirstChild("Humanoid")
				if human then
					human:TakeDamage(Damage)
					bulletClone:Destroy() -- Had to add this here as it would instantly kill you lolz
				end
				wait(3)
				bulletClone:Destroy()
			end)
		end
	end
end


a remix of your turret code to follow the target humanoid when it "sees it" :)

Integrated FPS code used for the Firing sequence, Since this code is running every game tick!.

Make the turret Follow you and fire code:

local RS = game:GetService("ReplicatedStorage")
local bullet = RS:WaitForChild("Bullet")

local Turret = script.Parent

local fireRate = 1


local Damage = 20
local bulletSpeed = 250
local detectDistance = 50


function getHumanoidTarget()
	local target = nil
	local Dist = detectDistance 
	for k,v in pairs(workspace:GetChildren()) do
		local Humanoid = v:FindFirstChildOfClass("Humanoid")
		local Torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if(Humanoid ~= nil and Humanoid.Health > 0 and Torso ~= nil) then
			local dist = (Torso.Position - Turret.Position).magnitude
			if(dist < Dist) then
				Dist = dist
				target = v
			end
		end
	end
	return target
end

local t = 0

local FPS = 0
local time = tick()


while true do
	--// FPS Code 
	local NowTime = tick()
	local dt = NowTime - time
	time = tick()
	
	local FPS = (1/dt) -- the frames per second we're running at!
	--// End of FPS Code
	
	
	local target = nil
	local tgt = getHumanoidTarget()
	if(tgt ~= nil) then
		local torso = tgt:FindFirstChild("Torso") or tgt:FindFirstChild("HumanoidRootPart")
		if(torso ~= nil) then
		if (torso.Position - Turret.Position).magnitude <= detectDistance then
			local raycastParams = RaycastParams.new()
			raycastParams.FilterDescendantsInstances = {workspace.Turret}
			raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

			local BulletPathResult = workspace:Raycast(Turret.Position,(torso.Position - Turret.Position).Unit*detectDistance, raycastParams)

			-- Problem begins here -- should be fixed!
				if BulletPathResult.Instance == torso 
					or BulletPathResult.Instance.Parent:FindFirstChild(torso.Name) then
				print("Targeting the humanoid")
					target = torso
			else 
				target = nil
				print("Object is in the way")
			end
			--problem ends here
		end
		end
		if target then
			local torso = target

			Turret.CFrame = CFrame.new(Turret.Position, torso.Position)
			if(t%math.floor((fireRate*FPS) +0.5) == 0) then -- fire according to fireRate * FPS 
				print("Fire")
				local bulletClone = bullet:Clone()
				bulletClone.Parent = game.Workspace
				bulletClone.Position = Turret.Position

				bulletClone.Velocity = Turret.CFrame.LookVector * bulletSpeed

				bulletClone.Touched:Connect(function(hit)
					local human = hit.Parent:FindFirstChild("Humanoid")
					if human then
						human:TakeDamage(Damage)
						bulletClone:Destroy()
					end
					wait(3)
					bulletClone:Destroy()
				end)
			end
		end
	end
	wait()
	-- advance time by 1 tick...
	t = t +1
end

2 comments

0

Thanks a lot! I'll implement this later to my turret, I just have one question, that is do I have to use both scripts or I just choose the system I want to use? (I want to use the first one just because it's easier to understand for me and I haven't leaned about stuff like ticks and stuff like that yet.)

0

either one will work., the 2nd one works on game tick. though its a little buggy when it comes to changing the firerate (it tends to be a machinegun or not fire sometimes), since i wrote it in 5 mins lol :P

This discussion is preserved as it was. New answers, comments, and votes are closed.