Jump to content

4 wheel landing


Timiimit

Recommended Posts

Hello all!

I haven't post for a very long time now mostly because i am using wiki :D. Does anyone know how to detect that vehicle landed on 4 wheels (not 0 XY rotation, but 0 XY rotation relative to the element that player landed on)? i have no clue how to even find element that vehicle landed on... please help!

Link to comment

The easiest way i can think of is to use getElementMatrix to get a vector that points up from the car, and compare that vector to the normal vector of the hit element you get from onClientVehicleCollision.

ooooor, onClientVehicleCollision->use getElementMatrix with getElementBoundingBox to get the approximate position of the wheels, and use isLineOfSightClear to check if all the wheels are colliding with something. Start check from wheel position to inverted normal vector direction of the hit element (which you get from onClientVehicleCollision event).

Link to comment

I haven't learned matrices in school yet so i'm not sure how they work (all i know about them, is that they are table of numbers). Could anyone show me how you get the up vector of the vehicle and the up vector of the surface of collision (onClientVehicleCollision).

Link to comment
addEventHandler("onClientVehicleCollision", root, 
function(hitElement, force, bodypart, colX, colY, colZ, normX, normY, normZ) 
    -- normX, normY, normZ are the components of the normal vector that is the surface 
    -- > the direction that the surface you hit is poiting in 
    local vehicle = getPedOccupiedVehicle(localPlayer) 
    -- Only check if vehicle landed on 4 wheels if the vehicle that collided was yours 
    if(source ~= vehicle)then return end 
    local m = getElementMatrix(vehicle) 
    -- m[1] is vector pointing right (x vector), m[2] is the vector poiting forwards (y vector), 
    -- and m[3] is the vector pointing up (z vector) 
    local vecX, vecY, vecZ = m[3][1], m[3][2], m[3][3] 
    -- compare vecX, vecY and vecZ with normX, normY, normZ to see how big the difference is between them 
end) 

Link to comment

this is what i got:

function checkLanding (hitElement, force, bodypart, colX, colY, colZ, normX, normY, normZ) 
    if(source ~= veh)then return end 
    local m = getElementMatrix(veh) 
    local vecX, vecY, vecZ = m[3][1], m[3][2], m[3][3] 
    local nRot = 8 
    if not wasOnGround and (vecZ - normZ <= nRot) then 
        outputChatBox("vZ: " .. vecZ .. ", normZ: " .. normZ) 
    end 
end 
addEventHandler("onClientVehicleCollision", getRootElement(), checkLanding) 

wasOnGround is isVehicleOnGround of the previous frame.

i thought that normZ is up vector of collision, but now i see that all normX, normY and normZ are direction. So how am i able to compare normX, Y and Z with ony one vecZ?

(im not sure that i understand the picture here)

Link to comment

Ah, you got it wrong.

normX, normY and normZ are together ONE 3d vector and they together tell what direction the vector is facing, and same for vecX, vecY and vecZ. You could think of vecX, vecY and vecZ as offsets in x, y and z direction. Which means that if you do

local object = createObject(2811, 0, 0, 0) 
addEventHandler("onClientRender", root, 
function() 
local vehicle = getPedOccupiedVehicle(localPlayer) 
local x, y, z = getElementPosition(vehicle) 
local m = getElementMatrix(vehicle) 
-- vecX, vecY and vecZ are values between -1 and 1, the same for normX, normY and normZ 
local vecX, vecY, vecZ = m[3][1], m[3][2], m[3][3] 
setElementPosition(object, x + vecX, y + vecY, z + vecZ) 
end) 

then the object (flower pot) will be above the vehicle, no matter your vehicle rotation.

normX, normY and normZ work the same way, they are offset in the direction that the surface if facing.

Also, onClientVehicleCollision is triggered before collision reaction, which means you dont need to check if vehicle was on ground the previous frame, also isVehicleOnGround is very inaccurate - doesn't work with all vehicles and only works on flat surfaces (doesn't work on slanted road, for example either).

The easiest thing you could do if you dont understand vectors well, is to do

local diffX, diffY, diffZ = math.abs(vecX - normX), math.abs(vecY - normY), math.abs(vecZ - normZ) 

and check if diffX, diffY and diffZ are smaller than small values, like 0.1 or something.

Link to comment

i did:

function checkLanding (hitElement, force, bodypart, colX, colY, colZ, normX, normY, normZ) 
    if(source ~= veh)then return end 
    local m = getElementMatrix(veh) 
    local vecX, vecY, vecZ = m[3][1], m[3][2], m[3][3] 
    local nRot = 0.05 
    if math.abs(vecX - normX) <= nRot and math.abs(vecY - normY) <= nRot and math.abs(vecZ - normZ) <= nRot then 
        outputChatBox("landed like a boss!") 
    end 
end 

and i get 0-2 outputs (depends on the speed) when i'm not even in the air yet (still on ramp or when ground angle changes) and 1-3 outputs when i land.

Link to comment

onClientVehicleCollision is triggered everytime you collide with something (it will trigger if you drive straight into wall for example).

You could check if the vehicle velocity is almost the opposite of the surface normal (the differences can be very big, since you can land with z velocity being very low, while x or y velocity being high).

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...