Trying to make a Gun turrent look towards the nearest target but having issue

I am trying to find the nearest target by using tables with the distance of each player to the gun turrent I have made but it keeps on telling me that my values are nil. Can someone please help me out?

Script:
local barrel = script.Parent
local bulletSpeed = 200
local damage = 1
local fireRate = 0.1
local range = 50
local bullet = game.ReplicatedStorage.Bullet

while wait(fireRate) do
local posibleTargets = {}
local target = nil
local distances = {}
for i , v in pairs(game.Workspace:GetChildren()) do

	if v:FindFirstChild("Humanoid") and (v:FindFirstChild("Torso").Position - barrel.Position).Magnitude < range then
		posibleTargets[i] = v.Torso
	end
	
	for i , distance in pairs(posibleTargets) do
		distances[i] = (barrel.Position - distance.Position).Magnitude
	end
	table.sort(distances)
	for i,v in pairs(posibleTargets) do
		if (v.Position - barrel.Position).Magnitude >= distances[0+i] and (v.Position - barrel.Position).Magnitude < distances[1+i] then
			target = v
		end
	end
end
--TARGET HAS BEEN FOUND!!

barrel.CFrame = CFrame.new(barrel.Position,target.Position)

end


I’m confused as to why you are going through the distances table when table.sort() goes through values and returns it from highest to lowest (with a function) so, the table.sort() should look something like this:

table.sort(distances, function(a,b)
	if a > b then
		return true
	end
end)

distances[#distances]

you literally havent put any values into the table its just an empty table you are trying to index your code goes like this

yo need to use table.insert(PossibleTargets, V.Torso)

he does insert them into a table,

right here.

Been looking through it a bit , is it possible that the locations of the i , v loops are making it break?

ah yes brain dead me sorry sorry
but still something bout this code doesnt sit right w me

my recommendation to improve efficiency is:

  • keep all the characters in a folder in workspace and loop through that folder instead of the entire workspace

  • calculate each players distance as you go have a variable called highest distance = math.huge
    if the currecnt player u are iterating over has a smaller distnace than the current highest set him to the target

thing to mind out for
on player deaths return them to the character folder

Thanks I will try that but for learning sake I still want to know what is going wrong here.


overlapping variable names

your nested for loops have the same index variables

Thanks for the help guys but I found out what was going wrong. Since there is only one character in range the second variable in the table was nil , so I changed it so that that part of the script only runs if ther is more than one person in the area, although overlapping variables was partly the issue. Thanks for the help guys.

New Scripst:
local barrel = script.Parent
local bulletSpeed = 200
local damage = 1
local fireRate = 0.1
local range = 50
local bullet = game.ReplicatedStorage.Bullet

while wait(fireRate) do
local posibleTargets = {}
local target = nil
local distances = {}
for a , v in pairs(game.Workspace:GetChildren()) do

	if v:FindFirstChild("Humanoid") and (v:FindFirstChild("Torso").Position - barrel.Position).Magnitude < range then
		posibleTargets[a] = v.Torso
	end
	
	for i , distance in pairs(posibleTargets) do
		distances[i] = (barrel.Position - distance.Position).Magnitude
	end
	table.sort(distances)
	for b,torsos in pairs(posibleTargets) do
		if (torsos.Position - barrel.Position).Magnitude >= distances[0+b] then
			if distances[1+b] ~= nil then
				if (torsos.Position - barrel.Position).Magnitude < distances[1+b] then
					target = torsos
				end
			else
				target = torsos
			end
		end
	end
end
--TARGET HAS BEEN FOUND!!

barrel.CFrame = CFrame.new(barrel.Position,target.Position)

end