Find nearest player/entity with condition.

What is the most efficient way to find the nearest player satisfying a condition. eg find nearest player with health > 50

My current method is looping through all the players, checking the condition and comparing the distance with the last player who matched the conditions. Is this the most efficient way of doing it?

Not sure if it is more efficient, but you could try ents.FindInSphere and loop through those.

I wouldn’t use ents.FindInSphere because it requires to loop through all entities in range which might be more than players.
Also the nearest player might not be in the sphere that you defined and you have to use a bigger radius thus leading to more entities to loop through.

I think you should just keep looping through all players, unless you are hosting a 128 slots server it shouldn’t use too much performance anyways

Sounds like an aimbot’s target finding routine :stuck_out_tongue:

Anyway, looping through all the players is pretty much the most efficient way to do it as far as I have seen. Make sure you check the things that are most likely to be false first.

Actually for an rp thing, when someone dies to make nearby people say “good god” and stuff. I don’t want all players to say it since it would just sound rubbish, don’t want someone on the other side of the map saying it as it would be totally out of context.

Thanks for your help everyone.

[lua]
–[[
Finds the closest player to a given position by looping through
each player and determining if their distance is lower than the
last. This function will return the closest player and the distance for
that player.
–]]
function FindClosestPlayer(position)
local distance = 32768 – maximum map size.
local client

for k, v in pairs(player.GetAll()) do
	local theirDistance = v:GetPos():Distance(position)

	if (theirDistance < distance) then
		distance = theirDistance
		client = v
	end
end

return client, distance

end
[/lua]

I also put in a break. If the player is within 200 units stop looking. Would this be more efficient in most cases?
Reason being if a person is within 200 units anyway they have probably seen the event so cna comment on it and it stops the loop so stops checking the rest of the players.

This is hooked to player death so killer and victim and players.

It will proceed to check if playerWitness is killer if true then play taunt, else say “oh god!”



			local playerWitness = killer
			local distancePlayer = 30000
			
			for k,v in pairs(player.GetAll()) do
				if v:GetPos():Distance(victim:GetPos()) < distancePlayer and v:alive() and v != victim then
					distancePlayer = v:GetPos():Distance(victim:GetPos())
					playerWitness = v	
				end
				-- 200 is close enough no point in looping thru every1
				if distancePlayer < 200 then break end
			end



Will the break generally make it less expensive

Its part of a larger function so the indentation is a lil skew wiff

An unnoticeable difference. You could just return if there is no more code in the function that needs running though.

Thank you,
There is more code though. The playerwitness is used abit later on.

Thanks for your help everyone.