[HELP] Issues with GetClosestVehicle and distance check

Hey,

First off, I’m new to coding and trying to learn/improve. But I’m posting here since I’m stuck even though I have tried to find the solution in documentation and examples from other scripts.

I’m currently trying to build a food truck script using esx and ox_lib. The script works as I want it to, except that I haven’t been able to add a distance check. I don’t want players to be able to sell/buy things across the entire map.

This is the part I’m currently struggling with:

local Player = GetPlayerPed(-1)
local PlayerPos = GetEntityCoords(Player)
local Foodtruck = GetClosestVehicle(PlayerPos.x, PlayerPos.y, PlayerPos.z, 5, GetHashKey(‘taco’), 0)

if not CanServe and Foodtruck then
Trigger check-in menu
elseif CanServe and Foodtruck then
Trigger menu to sell products

My understanding is that I don’t really understand how the GetClosestVehicle native works since the menus still get triggered no matter how far away from the taco truck I am.

Can someone explain what I’m doing wrong? Or is there a better way of doing this with natives or Ox_Lib? Thank you in advance!

Tl’dr: Don’t use the GetClosestVehicle native. It is unreliable depending on the situation and the flags just make it annoying to work with.

ox_lib probably has a function, but I’m not familiar with it, so here is an example I’m usually using edited with a modelHash check:

function GetClosestVehicle(position, maxRadius, modelHash)
	local distance = maxRadius or 1000.0
	local closestVehicle

	local vehicle = GetGamePool("CVehicle")
	for i = 1, #vehicles do
		if (modelHash == GetEntityModel(vehicles[i])) then
			local dist = #(GetEntityCoords(vehicles[i]) - position)
			if (dist < distance) then
				distance = dist
				closestVehicle = vehicles[i]
			end
		end
	end

	return closestVehicle
end

You should cache the game pool vehicle in a local variable. This speeds up the loop significantly while making the code more readable.

function GetClosestVehicle(position, maxRadius, modelHash)
	local distance = maxRadius or 1000.0
	local closestVehicle

	local pool = GetGamePool("CVehicle")
	for i = 1, #pool do
		local vehicle = pool[i]
		if (modelHash == GetEntityModel(vehicle)) then
			local dist = #(GetEntityCoords(vehicle) - position)
			if (dist < distance) then
				distance = dist
				closestVehicle = vehicles
			end
		end
	end

	return closestVehicle
end

That really depends on the use case though. We are talking a list of numbers and there is no additional nesting being used. Memory allocation also takes time, keep that in mind.

Even if it is faster in this case, it is probably absolutely negligible. It could impact garbage collection though.

That being said: Yes, caching can be extremely beneficial on performance, especially when talking about nested data.