Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[FiveM] calculate visualize dot product and angle between player and closest vehicle
local entityEnumerator = {
__gc = function(enum)
if enum.destructor and enum.handle then
enum.destructor(enum.handle)
end
enum.destructor = nil
enum.handle = nil
end
}
local function EnumerateEntities(initFunc, moveFunc, disposeFunc)
return coroutine.wrap(function()
local iter, id = initFunc()
if not id or id == 0 then
disposeFunc(iter)
return
end
local enum = {handle = iter, destructor = disposeFunc}
setmetatable(enum, entityEnumerator)
local next = true
repeat
coroutine.yield(id)
next, id = moveFunc(iter)
until not next
enum.destructor, enum.handle = nil, nil
disposeFunc(iter)
end)
end
function EnumerateObjects()
return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject)
end
function EnumeratePeds()
return EnumerateEntities(FindFirstPed, FindNextPed, EndFindPed)
end
function EnumerateVehicles()
return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle)
end
function EnumeratePickups()
return EnumerateEntities(FindFirstPickup, FindNextPickup, EndFindPickup)
end
function Smallest(tbl, getter)
if #tbl == 0 then return nil end
local ele = tbl[1]
local smallest = getter(ele)
for i = 2, #tbl do
local val = getter(tbl[i])
if val < smallest then
smallest = val
ele = tbl[i]
end
end
return ele
end
function GetAllVehicles()
local ret = {}
for veh in EnumerateVehicles() do
table.insert(ret, veh)
end
return ret
end
local function DrawStr(text, r, g, b, x, y, width, height)
SetTextColour(r, g, b, 255)
SetTextScale(width, height)
SetTextFont(0)
SetTextWrap(0.0, 1.0)
SetTextCentre(true)
SetTextDropshadow(0, 0, 0, 0, 0)
SetTextEdge(1, 0, 0, 0, 205)
SetTextEntry("STRING")
AddTextComponentString(text)
DrawText(x, y)
end
local function radToDeg(r)
return r * 180 / math.pi
end
local function atan2(y, x)
if x > 0 then
return math.atan(y/x)
elseif x < 0 and y >= 0 then
return math.atan(y/x) + math.pi
elseif x < 0 and y < 0 then
return math.atan(y/x) - math.pi
elseif x == 0 and y > 0 then
return math.pi/2
elseif x == 0 and y < 0 then
return math.pi/-2
else
return nil
end
end
Citizen.CreateThread(function()
while true do
local myCoords = GetEntityCoords(GetPlayerPed(-1))
local veh = Smallest(GetAllVehicles(), function(veh) return #(GetEntityCoords(veh) - myCoords) end)
if veh ~= nil then
local heading = GetEntityHeading(veh)
local vehPos = GetEntityCoords(veh)
local vehForward = GetEntityForwardVector(veh)
vehForward = vec3(vehForward.x, vehForward.y, 0)
local vehToPlr = norm(myCoords - vehPos)
vehToPlr = vec3(vehToPlr.x, vehToPlr.y, 0)
DrawLine(vehPos, vehPos + (vehForward*5), 255,0,0,255)
DrawLine(vehPos, vehPos + (vehToPlr*5), 0,255,0,255)
local angle = atan2(cross(vehForward, vehToPlr).z, dot(vehForward, vehToPlr))
DrawStr(("Angle: %.0f"):format(radToDeg(angle)), 255, 0, 0, .5, .5, .5, .5)
DrawStr(("Dot: %.2f"):format(dot(vehForward, vehToPlr)), 255, 0, 0, .5, .55, .5, .5)
end
Wait(0)
end
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment