I am having an issue where after so many markers have been placed they start to not show up, how would I be able to only draw a marker when someone is near it?
Check the distance between the player and the marker.
If the marker is close enough to be seen, draw it. If not, don’t.
Thanks, I am pretty new to coding / lua could give me an example?
Firstly you probably should show the code snippet, you use for drawing the markers.
At the end of the day though, the pseudo-code should look like this:
-- 1. get marker coords
-- 2. get player coords
-- compare them
-- if smaller than x (the draw distance you want, let's say 20), draw
-- else don't draw
local markerCoords = { x: '123.0', y: '123.0', z: '123.0' } -- this can be taken from the config for example
local playerCoords = GetEntityCoords(PlayerId()) -- not sure if that's the correct syntax though
local distance = GetDistanceBetweenCoords(table.unpack(markerCoords), table.unpack(playerCoords), true) -- comparing the values
if distance < 20 then
DrawMarker('blablabla', 1, 2, 3) -- draw the marker
end
Above code is totally from the top of my head, so it naturally won’t work, but I just wanted to show you the steps. Read more about the methods here: https://runtime.fivem.net/doc/natives/
EDIT: changed the if statement
I would have used Lua vector math to get the distance, and the distance > 20
check seems to be reversed, but other than that I am in full agreement with Mentozz.
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
local ped = GetPlayerPed(-1)
local playerPos = GetEntityCoords(ped, true)
for i,pos in pairs(INTERIORS) do
DrawMarker(1, pos.x, pos.y, pos.z-1.02, 0, 0, 0, 0, 0, 0, 0.7,0.7,0.8, 255,255,255, 200, 0, 0, 2, 0, 0, 0, 0)
if (Vdist(playerPos.x, playerPos.y, playerPos.z, pos.x, pos.y, pos.z) < 1.0) and (not PED_hasBeenTeleported) then
POS_actual = pos.id
if not gui_interiors.opened then
gui_interiors_OpenMenu()
end
end
end
end
end)
This is where I am drawing the marker.
How would I make it work with this?
Move the Vdist call to before drawing the marker, and store the value it returns.
Then compare that to whatever you want the draw range to be. If it’s nearer than that, do the draw.
In the existing if check for the distance, put in the same variable.
Sorry, still a little confused.
local distance = Vdist(playerPos.x, playerPos.y, playerPos.z, pos.x, pos.y, pos.z)
Does this look right?
Yes, so far so good.
(I mean, I wouldn’t use Vdist at all, but let’s not confuse the issue!)
if distance > 20 then
for i,pos in pairs(INTERIORS) do
DrawMarker(1, pos.x, pos.y, pos.z-1.02, 0, 0, 0, 0, 0, 0, 0.7,0.7,0.8, 255,255,255, 200, 0, 0, 2, 0, 0, 0, 0)
if (Vdist(playerPos.x, playerPos.y, playerPos.z, pos.x, pos.y, pos.z) < 1.0) and (not PED_hasBeenTeleported) then
POS_actual = pos.id
if not gui_interiors.opened then
gui_interiors_OpenMenu()
end
end
end
end
end)
This is most definitely wrong help me out with this here.
Hey, thanks for your help! After some playing around I got it to work! Here is the final code.
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
local ped = GetPlayerPed(-1)
local playerPos = GetEntityCoords(ped, true)
for i,pos in pairs(INTERIORS) do
local distance = Vdist(playerPos.x, playerPos.y, playerPos.z, pos.x, pos.y, pos.z)
if distance < 500 then
DrawMarker(1, pos.x, pos.y, pos.z-1.02, 0, 0, 0, 0, 0, 0, 0.7,0.7,0.8, 255,255,255, 200, 0, 0, 2, 0, 0, 0, 0)
if (Vdist(playerPos.x, playerPos.y, playerPos.z, pos.x, pos.y, pos.z) < 1.0) and (not PED_hasBeenTeleported) then
POS_actual = pos.id
if not gui_interiors.opened then
gui_interiors_OpenMenu()
end
end
end
end
end
end)
I didn’t test this, so don’t use it as a solution. It’s just an illustration of what I mean.
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
local ped = PlayerPedId()
local playerPos = GetEntityCoords(ped, true)
for i,pos in pairs(INTERIORS) do
local distance = Vdist(playerPos.x, playerPos.y, playerPos.z, pos.x, pos.y, pos.z)
if distance < 20 then
DrawMarker(1, pos.x, pos.y, pos.z-1.02, 0, 0, 0, 0, 0, 0, 0.7,0.7,0.8, 255,255,255, 200, 0, 0, 2, 0, 0, 0, 0)
if distance < 1.0 and not PED_hasBeenTeleported then
POS_actual = pos.id
if not gui_interiors.opened then
gui_interiors_OpenMenu()
end
end
end
end
end
end)
See how I re-use the distance
variable so I don’t have to do a second Vdist?
Also, PlayerPedId()
returns the same as GetPlayerPed(-1)
, but is way way way faster.
Depending on how you store INTERIORS
, you can also move distance
over to using CfxLua vector math, and replace Vdist
entirely. That will also speed it up by a lot.
Having the marker visible at 500 meters is perhaps a little overkill? Draw one in an open, visible place and measure your distance from it, and you’ll see it becomes largely irrelevant as far as on-screen information goes, before 150 meters. Add buildings in the way to that, and I’m sure 100m is fine.
This is really nitpicking, though. Congratulations on solving it!
The only thing I would say can be improved, it not initializing the distance
variable inside of the loop, but rather outside of it and then just changing the value, like this:
local distance = nil
for i,pos in pairs(INTERIORS) do
distance = Vdist(playerPos.x, playerPos.y, playerPos.z, pos.x, pos.y, pos.z)
...
end
It’s a free memory optimization right here
Measured against the native overhead of the Vdist, I’d say that’s not going to be noticeable, but you are technically correct, and that is the best kind of correct!