Player Iteration struggles

I’m trying to get the closet player by a maximum radius whilst getting the actual closest player, however it sometimes struggles to even iterate through players.

local _ClosetPlayer = function()
	local maximumStuds = 50
	
	local _FakePlayer = nil
	
	local _Player = nil
	
	while not _Player do
		for _,v in _Players:GetPlayers() do
			if v.Character and v.Character:GetAttribute("_spawned") then
				
				local studsCached = v.Character.PrimaryPart.Position.Magnitude
				if studsCached < maximumStuds then
					maximumStuds = studsCached
					_FakePlayer = v
				end
				
			end
			task.wait()
		end
		if _FakePlayer then
			_Player = _FakePlayer
		end
		task.wait()
		print(_Player, _FakePlayer)
	end
	return _Player
end
4 Likes

local studsCached = v.Character.PrimaryPart.Position.Magnitude

To calculate the distance of something, you’ll need two vectors and will want to use the following:

distance = (a.Position - b.Position).Magnitude

Additionally, you’re overriding the maximumStuds variable with maximumStuds = studsCached.
I’m not sure if I understand what you mean, do you want to calculate the closest position of a player with another?

1 Like

Basically yes, I don’t want to get the player who’s like 49 studs away instead of the actual close players who’s 5 studs away.

That is the maximum studs being overwritten with the last closest distance

2 Likes

Thanks for clearing this up! The only detail here is that you’ll need a separate instance to compare distances do.
You’ll want to do something like this:

-- assuming that "Part" is a separate Instance
local studsCached = (v.Character.PrimaryPart.Position - Part.Position).Magnitude
if studsCached < maximumStuds then
    maximumStuds = studsCached
end

Also! I think I figured out why your script fails to iterate through the players.

Your loop starts with “while not _Player do” (so it only runs while _Player is false or nil), but later _Player is set to _FakePlayer, preventing the loop from happening again.

Hope this solves your problems! Let me know if you need any more help or don’t understand something.

I’m well aware, I do this is to basically recalculate the overwritten maximumstuds aka use it to see if any player is close to that magnitude.

Is this what you’re trying to do?

local function findClosestPlayerTo(point: Vector3): Player?
	local currentP, currentD = nil, math.huge
	for _, player in pairs(game.Players:GetPlayers()) do
		local character = player.Character 
		if not character then continue end
		local pos = character:GetPivot().Position 
		local distance = (point-pos).Magnitude 
		if distance < currentD then
			currentP = player 
			currentD = distance 
		end
	end
	return currentP
end

task.wait(5) --so player loads before it runs
print(findClosestPlayerTo(workspace.Baseplate.Position))

Kind off but instead of a player getting other parts its a little part, it spawns, checks for the actual nearby players (gets the most recent player then tries to compare if any player is closer than the previous) within a maximum radius of 50 studs, I tried to achieve this by storing the most recent magnitude then comparing the next if any, but sometimes it doesn’t even iterate through players and struggles.

local _ClosetPlayer = function()
	local maximumStuds = 50
	
	local _FakePlayer = nil
	
	local _Player = nil
	
	while not _Player do
		for _,v in _Players:GetPlayers() do
			if v.Character and v.Character:GetAttribute("_spawned") then
				
				local studsCached = (v.Character.PrimaryPart.Position - _Character.PrimaryPart.Position).Magnitude
				if studsCached < maximumStuds then
					maximumStuds = studsCached
					_FakePlayer = v
				end
				
			end
			task.wait()
		end
		if _FakePlayer then
			_Player = _FakePlayer
		end
		task.wait()
		print(_Player, _FakePlayer)
	end
	return _Player
end

print("trying to get player")

_path:Run(_ClosetPlayer())

You aren’t checking if the character has a HumanoidRootPart that is the PrimaryPart of a character model before indexing it with .Position which will cause an error if it isn’t there. Also you’re yielding code within the player loop that generally isn’t a good idea(the task.wait within the player loop). Instead yielding should only occur to the outside loop.

Another issue may be your _Character variable in case there’s a chance of said character being destroyed(or its root part getting destroyed).

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.