[How-To] Get the closest entity to your character (LUA)

Well done.

It’s good, but there was room for improvement again, in my opinion. Some of the changes will make it faster, some are just better practice when writing code and others are my personal preference. But the changes include;

  • Not getting PlayerPedId() multiple times
  • Not creating new vars when you can check/reassign the parameters
  • Not assigning the game pool to a var and looping, but instead looping from it directly
  • Not using global vars in a loop that aren’t needed that scope, which can alter expected results
  • Not looping with an integer index and assigning it to a new variable but instead looping in pairs
  • Cleaned up a lot of the check variables with less repetition of natives

It now looks like this. Feel free to give it a test;

function GetClosestEntity(entitytype, alive, targets, los, ignoreanimals, coords)

	-- Usage: GetClosestEntity("CPed", "alive", "any", "inlos", false, vector3(x, y, z))
	-- entitytype: "CPed", "CObject", "CVehicle", "CPickup"
	-- alive: "any", "alive", "dead" or (Vehicle only: "alivedriver", "deaddriver")
	-- targets: "any", "player", "npc" or (Vehicle only: "empty")
	-- los: "any", "notinlos", "inlos"
	-- ignoreanimals: true, false
	-- coords: vector3, {x, y, z} or nil for the player's coords

	local playerPed, closestEntity, closestDist, aliveCheck, losCheck = PlayerPedId(), -1, -1, false, false

	-- Get peds, objects, vehicles or pickups, according to the param
	entitytype = entitytype or "CPed"

	-- Get only alive or dead entities, according to the param
	alive = alive or "alive"

	-- Get entities that are only players or npcs or both, according to the param
	targets = targets or "any"

	-- Get only entities in or out of your line of sight, according to the param
	los = los or "inlos"

	-- Ignore entities that are animals according to the ignoreanimals param
	ignoreanimals = ignoreanimals or false

	-- Get specified coords or coords of current player if empty
	coords = coords or GetEntityCoords(playerPed)

	-- Loop through the game pool until closest entity is found.
	for index, entity in pairs(GetGamePool(entitytype)) do

		local driver = entitytype == "CVehicle" and GetPedInVehicleSeat(entity, -1) or -1

		-- Handles the alive param
		local aliveCheck =
			(alive == "any") or
			(alive == "alive" and not IsEntityDead(entity)) or
			(alive == "dead" and IsEntityDead(entity)) or
			(alive == "alivedriver" and driver > 0 and not IsEntityDead(driver)) or
			(alive == "deaddriver" and driver > 0 and IsEntityDead(driver))

		-- Handles the targets param
		local targetsCheck =
			(targets == "any") or
			(targets == "player" and IsPedAPlayer(driver == -1 and entity or driver)) or
			(targets == "npc" and driver == -1 and not IsPedAPlayer(entity)) or
			(targets == "npc" and driver > 0 and not IsPedAPlayer(driver)) or
			(targets == "empty" and driver == 0 and GetVehicleNumberOfPassengers(entity) == 0)

		-- Handles the los param
		local losCheck =
			(los == "any") or
			(los == "inlos" and HasEntityClearLosToEntity(playerPed, entity, 17)) or
			(los == "notinlos" and not HasEntityClearLosToEntity(playerPed, entity, 17))

		-- Handles the ignoreanimals param
		local ignoreanimalsCheck = (not ignoreanimals or (IsEntityAPed(entity) and GetPedType(entity) ~= 28))

		if entity ~= playerPed and aliveCheck and losCheck and targetsCheck and ignoreanimalsCheck then
			local distance = #(coords - GetEntityCoords(entity))
			if closestDist == -1 or distance < closestDist then
				closestEntity = entity
				closestDist = distance
			end
		end

	end

	return closestEntity, closestDist
end

local ent, dist = GetClosestEntity("CPed", "alive", "any", "inlos", false)
print(ent, dist)
if IsEntityAVehicle(ent) then
	print("Entity is a veh")
elseif IsEntityAPed(ent) then
	print("Entity is a ped")
elseif IsEntityAnObject(ent) then
	print("Entity is a object")
end
if IsEntityDead(ent) then
	print("Entity is dead")
else
	print("Entity is alive")
end