Jump to content

isLineOfSightClear distance


Drakath

Recommended Posts

local x, y, z = getElementPosition(peds) 
local matrix = getElementMatrix (peds) 
local isPathClear = true 
for i = 1, 10 do 
isPathClear = isLineOfSightClear (x, y, z, matrix[2][1] + matrix[4][1], matrix[2][2] + matrix[4][2], matrix[2][3] + matrix[4][3] - 0.8 + i*0.2, true, true, false, true) 
if (not isPathClear) then 
break 
end 
end 

This script detects if there is an obstacle. I make my ped jump when it detects it. But this script only works if a ped is 1 meter away from the obstacle. How can I make it to work if ped is right in front of the obstacle?

Link to comment
Did you know that the example in isLineOfSightClear shows how to make peds jump when there is an obstacle?

The example doesn't make them jump if an obstacle is right in front of them. It will make the ped jump only if he is 1 meter away from the obstacle. I want to make him jump even if he is 0 meters away.

From what I observed in the code and my own knowledge, it should force the ped to jump once, as soon as something is in front of the 1 meter detection. The following code is edited to make the ped jump every second until no obstacles are in the way

local t_Data = {} 
local jumpTimerInterval = 1000*1 --(1000ms x 1 = 1 second) This variable determines the interval between jumps, in ms [1000ms = 1 second] 
  
  
local function updateNPC () 
    if (not isElement(t_Data.ped) or (getElementHealth(t_Data.ped) == 0)) then 
        return toggleNPCFollower () 
    end 
  
    local t_PlayerPos = {getElementPosition(localPlayer)} 
    local t_PedPos = {getElementPosition(t_Data.ped)} 
  
    local intDistance = getDistanceBetweenPoints3D (t_PedPos[1], t_PedPos[2], t_PedPos[3], unpack(t_PlayerPos)) 
    if (intDistance < 4) then 
        setPedControlState (t_Data.ped, 'forwards', false) 
        return true 
    end 
  
    -- Calculate the rotation between ped and player position 
    local intPedRot = -math.deg (math.atan2(t_PlayerPos[1] - t_PedPos[1], t_PlayerPos[2] - t_PedPos[2])) 
    if intPedRot < 0 then intPedRot = intPedRot + 360 end; 
  
    setElementRotation (t_Data.ped, 0, 0, intPedRot, 'default', true) 
    -- At this point we know that the ped needs to move it 
    setPedControlState (t_Data.ped, 'forwards', true) 
  
    local bPathClear = true 
    local t_Matrix = getElementMatrix (t_Data.ped) 
  
    -- Calculate a position 1m ahead of ped 
    local int_RayX = t_Matrix[2][1] + t_Matrix[4][1] 
    local int_RayY = t_Matrix[2][2] + t_Matrix[4][2] 
    local int_RayZ = t_Matrix[2][3] + t_Matrix[4][3] 
  
    -- We cast 10 rays 1m ahead of the ped 
    for i = 1, 10 do 
        local intSourceX, intSourceY, intSourceZ = t_PedPos[1], t_PedPos[2], t_PedPos[3] 
  
        -- The target position height is identical to the center of the ped (1m above ground)  
        -- We lower this value by 0.5m to detect short obstacles 
        local intTargetX, intTargetY, intTargetZ = int_RayX, int_RayY, int_RayZ - 0.5 + i*0.2 
  
        bPathClear = isLineOfSightClear (intSourceX, intSourceY, intSourceZ, intTargetX, intTargetY, intTargetZ, true, true, false, true) 
        dxDrawLine3D (intSourceX, intSourceY, intSourceZ, intTargetX, intTargetY, intTargetZ, bPathClear and tocolor(255,255,255,255) or tocolor(255,0,0,255)) 
  
        if (not bPathClear) then 
            break 
        end 
    end 
  
    if isTimer(t_Data.jumpTimer) then killTimer(t_Data.jumpTimer) end 
    if (not bPathClear) then 
        setPedControlState (t_Data.ped, 'jump', true) 
        t_Data.jumpTimer = setTimer(function() setPedControlState (t_Data.ped, 'jump', false) setPedControlState (t_Data.ped, 'jump', true) end, jumpTimerInterval, 0) 
    else 
        setPedControlState (t_Data.ped, 'jump', false) 
    end 
  
    if (intDistance > 15) then 
        setPedControlState (t_Data.ped, 'sprint', true) 
    else 
        setPedControlState (t_Data.ped, 'sprint', false) 
    end 
end 
  
function toggleNPCFollower () 
    if (t_Data.ped) then 
        if (t_Data.updateNPCTimer) then 
            if (isTimer(t_Data.updateNPCTimer)) then 
                killTimer (t_Data.updateNPCTimer) 
            end 
        end 
        if (isElement(t_Data.ped)) then 
            destroyElement (t_Data.ped) 
        end 
        t_Data.ped = nil 
        return true 
    end 
  
    local intX, intY, intZ = getElementPosition (localPlayer) 
    local _, _, intRZ = getElementRotation (localPlayer) 
    local t_Matrix = getElementMatrix (localPlayer) 
  
    -- Calculate a position 4m behind local player 
    local intPedX = -4 * t_Matrix[2][1] + t_Matrix[4][1] 
    local intPedY = -4 * t_Matrix[2][2] + t_Matrix[4][2] 
    local intPedZ = -4 * t_Matrix[2][3] + t_Matrix[4][3] 
  
    t_Data.ped = createPed (0, intPedX, intPedY, intPedZ, intRZ) 
    t_Data.updateNPCTimer = setTimer (updateNPC, 50, 0) 
end 
addCommandHandler ('npc', toggleNPCFollower) 

Untested, but should work.

Link to comment

By the way, how can I increase the length of rays?

local t_Matrix = getElementMatrix (t_Data.ped) 
local int_RayX = t_Matrix[2][1] + t_Matrix[4][1] 
local int_RayY = t_Matrix[2][2] + t_Matrix[4][2] 
local int_RayZ = t_Matrix[2][3] + t_Matrix[4][3] 
for i = 1, 10 do 
local intSourceX, intSourceY, intSourceZ = t_PedPos[1], t_PedPos[2], t_PedPos[3] 
local intTargetX, intTargetY, intTargetZ = int_RayX, int_RayY, int_RayZ - 0.2 + i*0.2 
dxDrawLine3D (intSourceX, intSourceY, intSourceZ, intTargetX, intTargetY, intTargetZ, tocolor(255,0,0,255)) 
end 
  

This script draws 10 lines of 1 meter length. Let's say I want to increase that to 3 meters.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...