Skip to content

Testing a point

Michael Afrin edited this page Aug 22, 2020 · 2 revisions

Testing a Point with PolyZone

There is two ways to test whether a point is inside the zone. There is a more manual way, which includes directly using the isPointInside method on a particular zone, and then there is two helper functions which remove some of that boilerplate. These functions work on ALL zones (PolyZone, EntityZone, CircleZone, etc.).

Assuming we are using the "pinkcage" zone from here, the manual way to check if a point is inside the zone is as follows:

local insidePinkCage = false
Citizen.CreateThread(function()
    while true do
        local plyPed = PlayerPedId()
	local coord = GetEntityCoords(plyPed)
	insidePinkCage = pinkcage:isPointInside(coord)
	Citizen.Wait(500)
    end
end)    

"insidePinkCage" will be updated every 500 ms with whether the player's position is inside or outside the zone

The way to do this with the helper functions is as follows:

local insidePinkCage = false
pinkcage:onPlayerInOut(function(isPointInside, point)
    insidePinkCage = isPointInside
end)

which is actually an alias for:

local insidePinkCage = false
pinkcage:onPointInOut(PolyZone.getPlayerPosition, function(isPointInside, point)
    insidePinkCage = isPointInside
end)

onPointInOut will trigger the callback function we passed in function(isPointInside, point) every time the point enters or exits the zone

The point we are testing for is computed using the first thing we pass to onPointInOut. PolyZone.getPlayerPosition is a premade function that just returns the player's current position

A similar function, PolyZone.getPlayerHeadPosition exists, that returns the position of the player's head. This can be useful if your server has crouch and/or prone enabled, and you want players to be able to go underneath a zone.

The nice thing about onPointInOut is that the isPointInside parameter of the callback function will always represent whether the point has JUST entered or exited the zone.

pinkcage:onPointInOut(PolyZone.getPlayerPosition, function(isPointInside, point)
    if isPointInside then
	-- Point has just entered the zone
    else
	-- Point has just left the zone
    end
end)

An optional third argument exists for onPointInOut that controls the number of milliseconds between each point check. The default for this is 500 ms, but you can change it to any amount

local msBetweenPointCheck = 100
pinkcage:onPointInOut(PolyZone.getPlayerPosition, function(isPointInside, point)
    -- This function will now check every 100 ms whether the point has entered or exited the zone
end, msBetweenPointCheck)

Also, if the PolyZone.getPlayerPosition or PolyZone.getPlayerHeadPosition helpers don't work for what you are doing, you can use a custom callback for getting the point to test:

local insidePinkCage = false
pinkcage:onPointInOut(function()
    return GetEntityCoords(GetVehiclePedIsIn(PlayerPedId(), false))
end, function(isPointInside, point)
    insidePinkCage = isPointInside
end)

Here we pass in the following custom callback that returns the point to check:

function()
    return GetEntityCoords(GetVehiclePedIsIn(PlayerPedId(), false))
end

This function will return the position of the vehicle the player is currently in. Note that this is just an example, and in reality, PolyZone.getPlayerPosition will do this anyways.