Most optimized way to call event when nearby coordinates

what is the most clean and optimized way for a callback to be triggered when a player enters in x(10meters ecc) radius from x y z waypoint loaded in db
ex player is approaching x y z
13 meters, 12 meters, 11 meters 10 meters : trigger function
of course i can check with a for loop but i think it would be a waste of resource, is there a better optimized way?

tl;dr is there a way to set a trigger to activate when reaching inside a xyz coordinates radius or must i do it in the ugly and non optimized way of a while?

In order to detect if someone is within a certain distance from a point, you need to compute such distance. That can be done on the server (if using Onesync) or the client, I would recommend to keep that kind of stuff on the client tho.

The most optimized way to do so is to check the distance on a long interval. Such intervals can varry according to the distance previously calculated, reaching its minimum when the player is close.

so there is no way to set a trigger? this is an imperfect solution, that might be the only one and you might be right but if that’s the only way its kinda bad

Be aware that FiveM isn’t a full game engine. In Unity you can add just event triggers.
In our case, @Elio explained it very well.

Also it may look like bad or inefficient, but we have now pretty powerful CPU’s. They can handle a lot of instructions per second. (Unless you still have a processor from like 1951…)
(source : Instructions per second - Wikipedia)

thanks for your reply, does anyone have a code that could help me understand how to draw a shape with coordinates and check if you’re inside it?

not sure what other shape you want besides a circle…
In this resource, you can find a pretty good example of checking if you are inside :

If you want squares or other shapes, you will need to create all the math yourself. (maybe by tracking the 4 points and compare them with the ped’s coordinates)

Not sure if there is a huge demand for square zone detection.

we wrote our own script, but checking in a loop and comparing your position just constantly drops fps… it’s not a doable thing…

maybe the way of checking is not optimal for you.
Are you checking the position each frame ? once every 10 seconds ?
Why not do what Elio said, depending on the distance, check less or more often.
If the player is at [0,0] and your trigger at [1000,1000] no need to spam all the time.

Also make sure that when the player is in the zone or trigger, put that in a variable. So that you don’t have to check the position anymore.

If nothing like that helps. Without code it will be hard to help you.

check my profile, i wrote a new thread with the code, just make sure to refresh after a couple of minutes cause i discovered new findings.

This is my approche on a lightweight centralized coordinates differentiation script.

It is made so you can configure vector3 coordinates along with a corresponding key for them.
It changes the while loop tick time dynamically based on the nearest coordinates.
Events get sent across all client scripts wich you can then handle from anywhere.

Examples are in the code.

Average Resmon: 0.0ms

local points = { -- the key eg. 'bus' must be unique
    ['bus']     = vector3(454.4804, -599.1644, 28.56905),
    ['mower']   = vector3(-949.2208, 334.2767, 71.33098),
}

local requiredDistance = 10 --Meters

Citizen.CreateThread(function()
    local playerPos = GetEntityCoords(PlayerPedId())

    while true do
        local shortestDistance = math.huge
        for name,coords in pairs(points) do
            playerPos = GetEntityCoords(PlayerPedId())

            local distance = #(playerPos - coords)

            if distance < shortestDistance then
                shortestDistance = distance
            end

            if distance <= requiredDistance then
                TriggerEvent("YourScriptTrigger:"..name..":enteredRadius") -- Enter-event name that gets triggered across all client scripts

                while distance <= requiredDistance do
                    Citizen.Wait(100)
                    playerPos = GetEntityCoords(PlayerPedId())
                    distance = #(playerPos - coords)
                end

                TriggerEvent("YourScriptTrigger:"..name..":exitedRadius") -- Exit event that got triggered when leaving the radius
            end
        end
        Citizen.Wait(100 + math.floor(shortestDistance * 10)) -- Increses the waiting time by the player distance -> 500 meter == 5 seconds / 30m == 400 milliseconds += 100ms base tick
    end
end)

RegisterNetEvent("YourScriptTrigger:mower:enteredRadius") -- Example EventHandler on the player entering the radius 
AddEventHandler("YourScriptTrigger:mower:enteredRadius", function()
    EnteredZone()
end)

RegisterNetEvent("YourScriptTrigger:mower:exitedRadius") -- Example EventHandler on the player leaving the radius
AddEventHandler("YourScriptTrigger:mower:exitedRadius", function()
    LeftZone()
end)
2 Likes