Finding the closest player

Hi,I have always wonder how to sort a table for find the closest player.
After I a script a bit, it told me that the closest one was nothing.(And the whole table) How can I solve that?

local DistanceTable = script.Parent.DistanceDetection:GetChildren()
local SightTable = script.Parent.SightDetection:GetChildren()
local Service = game:GetService(“RunService”)

function Compare(InDistances,InSight)
local p = 0
local t = {}
for i = 1,#InDistances do
if InSight:FindFirstChild(InDistances[i]) then
p = p + 1
table.insert(t,p,(script.Parent.Base.Position - InDistances[i].Value.Torso).Magnitude)
end
end
table.sort(t)
print(table.concat(t))
end

Compare(DistanceTable,SightTable)

Note:I’m very new to table.

3 Likes

there is no need to sort a table if you only wish to find the closest player. Just have two varibles which hold the distance and the player. The loop would then check if the distance is shorter then assing the new shortest distance and player.

I would also use DistanceFromCharacter.

1 Like

Here’s my new script, but it’s not doing anything.

local DistanceTable = script.Parent.DistanceDetection:GetChildren()
local SightTable = script.Parent.SightDetection:GetChildren()
local Service = game:GetService(“RunService”)

function Compare(InDistances,InSight)
local p = 0
local t = {}
for i = 1,#InDistances do
if InSight:FindFirstChild(InDistances[i]) then
p = p + 1
table.insert(t,p,(script.Parent.Base.Position - InDistances[i].Value.Torso).Magnitude)
end
end
for x = 1,#t do
local Closest = 300
local temp1 = t[x-1]
local temp2 = t[x]
if x > 1 then
if temp2 > temp1 then
Closest = temp2
end
end
return Closest
end
end

Compare(DistanceTable,SightTable)

I have no idea what I’m doing.

Hello I am not sure what you’re actually trying to do but reading from your main post :
“Getting closest player”.

I just wrote a quick script to do so maybe you can read it and I guess learn a few things…
also @kingdom5 DistanceFromCharacter isn’t always the right choice, imagine if the game had 50 players you’d be doing 50 functions calls instead of just doing (pos1-pos2).magnitude
If you have any questions regarding the script feel free to ask! ( Also this doesn’t check if the players are visible/insight )

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer

local function GetClosest()
    local Character = LocalPlayer.Character
    local HumanoidRootPart = Character and Character:FindFirstChild("HumanoidRootPart")
    if not (Character or HumanoidRootPart) then return end

    local TargetDistance = math.huge
    local Target

    for i,v in ipairs(Players:GetPlayers()) do
        if v ~= LocalPlayer and v.Character and v.Character:FindFirstChild("HumanoidRootPart") then
            local TargetHRP = v.Character.HumanoidRootPart
            local mag = (HumanoidRootPart.Position - TargetHRP.Position).magnitude
            if mag < TargetDistance then
                TargetDistance = mag
                Target = v
            end
        end
    end

    return Target
end
10 Likes

You should be using DistanceFromCharacter for distance checks when applicable. It is made only for the task of distance checking from the players position. Roblox would not have included a function if it served no purposes/benafit to developers.

I am unsure why you are comparing the number of function calls vs using (pos1-pos2).magnitude? They both still use the same number of loops.

In terms of speed (pos1-pos2).magnitude is creating a new vector3 simply for you to get the magnitude so it will be slow. I would also expect the function DistanceFromCharacter to run on the C++ side of things to improve speed. But that is all theoretical so we should test it.

Run the script in the post blow to test the differences in speed but is a little unfair on the tests.

Here is another test that is a bit more fair as all tests are setup the same way.

local Players = game:GetService"Players"
local plr = Players:FindFirstChildWhichIsA"Player" or Players.PlayerAdded:Wait()
local char = plr.Character or plr.CharacterAdded:Wait()

while wait(3) do
	local vec = Vector3.new(100,100,100)
	local tmpVec = char.HumanoidRootPart.Position
	local sqrt = math.sqrt
	local runAmount = 100000
	
	print('Magnitude')
	local tmp = tick()
	for i=1,runAmount do
	    local dist = (tmpVec-vec).Magnitude
	end
	print(tick()-tmp)
	print('result', (tmpVec-vec).Magnitude)
	print('-----------')
	
	print('DistanceFromCharacter')
	local tmp = tick()
	for i=1,runAmount do
	    local dist = plr:DistanceFromCharacter(vec)
	end
	print(tick()-tmp)
	print('result', plr:DistanceFromCharacter(vec))
	print('-----------')
	
	print('just math')
	local tmp = tick()
	for i=1,runAmount do
		local dist = sqrt(
			(tmpVec.X - vec.X) ^ 2
			+ (tmpVec.Y - vec.Y) ^ 2
			+ (tmpVec.Z - vec.Z) ^ 2
			)
	end
	print(tick()-tmp)
	print('result', sqrt(
			(tmpVec.X - vec.X) ^ 2
			+ (tmpVec.Y - vec.Y) ^ 2
			+ (tmpVec.Z - vec.Z) ^ 2
	))
	print('-----------')
end

The result I get is that DistanceFromCharacter is faster. This test was done using Faster Lua.

Output

  Magnitude
  0.014677762985229
  result 171.1291809082
  -----------
  DistanceFromCharacter
  0.0095052719116211
  result 170.17626953125
  -----------
  just math
  0.020348310470581
  result 171.12918157221
  -----------
7 Likes