From the reference libraryFiveM

Shared

ox/ox_lib/Zones/Shared.mdx

Shared

A highly performant spatial check system for the game world. Zones define a 3D area (sphere, box, or polygon) and evaluate whether a position is inside or outside that region - similar to a colshape.

Internally, Zones utilise a spatial grid to efficiently narrow down relevant zones before performing precise position tests.

For Lua, this replaces PolyZone and leverages the GLM library for high performance and memory efficiency.

Zones are also available in JS, utilising our utility library for geometry, grid, and spatial operations.

Server-side zones do not support player trigger events. The onEnter, onExit, and inside handlers are unavailable.

Lua and JavaScript zones are not API compatible. The TypeScript definitions and TSDoc comments in the npm package serve as the authoritative reference for the JavaScript API.

Polygon/Prism Zone

Creates a polygon from the given vertices, which is then placed in the world and extruded to the given height to form a 3D shape.

lib.zones.poly(data)
  • data: table
    • points: vector3[]
      • An array of 3d points defining the polygon's shape.
    • thickness?: number
      • The height of the polygon, defaulting to 4.
    • onEnter?: function(self: table)
    • onExit?: function(self: table)
    • inside?: function(self: table)
    • debug?: boolean
import { Zone } from "@overextended/ox_lib";
import { Vector2 } from "@overextended/core/vector";

Zone.Prism(vertices: Vector2[], height: number, z: number)

Box Zone

lib.zones.box(data)
  • data: table
    • coords: vector3
    • size?: vector3
      • Default: vec3(2, 2, 2)
    • rotation?: number
      • Angle in degrees, defaulting to 0.
    • onEnter?: function(self: table)
    • onExit?: function(self: table)
    • inside?: function(self: table)
    • debug?: boolean
import { Zone } from "@overextended/ox_lib";
import { Vector3 } from "@overextended/core/vector";

Zone.Cuboid(origin: Vector3, width: number, depth: number, height: number, heading?: number)

Sphere Zone

lib.zones.sphere(data)
  • data: table
    • coords: vector3
    • radius?: number
      • Default: 2
    • onEnter?: function(self: table)
    • onExit?: function(self: table)
    • inside?: function(self: table)
    • debug?: boolean
import { Zone } from "@overextended/ox_lib";
import { Vector3 } from "@overextended/core/vector";

Zone.Sphere(coords: Vector3, radius: number)

Methods > onEnter

A function called when the player enters the zone. It can be attached to the zone after instantiation, or in the data table if using Lua.

local function onEnter(self)
    print('entered zone', self.id)
end

zone.onEnter = onEnter
function onEnter(this: Zone) {
  console.log(`entered zone ${this.id}`)
}

zone.onEnter = onEnter;

Methods > onExit

A function called when the player exits the zone. It can be attached to the zone after instantiation, or in the data table if using Lua.

local function onExit(self)
    print('exited zone', self.id)
end

zone.onExit = onExit
function onExit(this: Zone) {
  console.log(`exited zone ${this.id}`)
}

zone.onExit = onExit;

Methods > inside

A function called when the player exits the zone. It can be attached to the zone after instantiation, or in the data table if using Lua.

local function inside(self)
    print('you are inside zone', self.id)
end

zone.inside = inside
function inside(this: Zone) {
  console.log(`you are inside zone ${this.id}`)
}

zone.inside = inside;

Methods > remove

Zones can be deleted by using the remove method.

local zone = lib.zones.box({...})

zone:remove()

Methods > contains

Tests if a point exists inside the zone, returning a boolean.

local zone = lib.zones.box({...})

if zone:contains(vec3(1, 1, 1)) then
    print('point is inside zone!')
end

Methods > setDebug

Enables or disables debug mode for a zone, optionally with custom colors.

local zone = lib.zones.box({...})

-- Enable debug with default colors
zone:setDebug(true)

-- Enable debug with custom colors
zone:setDebug(true, vec4(255, 0, 0, 100))

-- Disable debug
zone:setDebug(false)

Utility Functions > lib.zones.getAllZones

Returns all registered zones.

local zones = lib.zones.getAllZones()

Utility Functions > lib.zones.getCurrentZones

Returns all zones the player is currently inside.

local currentZones = lib.zones.getCurrentZones()

Utility Functions > lib.zones.getNearbyZones

Returns all zones near the player.

local nearbyZones = lib.zones.getNearbyZones()

Examples

function onEnter(self)
    print('entered zone', self.id)
end

function onExit(self)
    print('exited zone', self.id)
end

function inside(self)
    print('you are inside zone ' .. self.id)
end

local poly = lib.zones.poly({
    points = {
        vec(413.8, -1026.1, 29),
        vec(411.6, -1023.1, 29),
        vec(412.2, -1018.0, 29),
        vec(417.2, -1016.3, 29),
        vec(422.3, -1020.0, 29),
        vec(426.8, -1015.9, 29),
        vec(431.8, -1013.0, 29),
        vec(437.3, -1018.4, 29),
        vec(432.4, -1027.2, 29),
        vec(424.7, -1023.5, 29),
        vec(420.0, -1030.2, 29),
        vec(409.8, -1028.4, 29),
    },
    thickness = 2,
    debug = true,
    inside = inside,
    onEnter = onEnter,
    onExit = onExit
})

local sphere = lib.zones.sphere({
    coords = vec3(442.5363, -1017.666, 28.65637),
    radius = 1,
    debug = true,
    inside = inside,
    onEnter = onEnter,
    onExit = onExit
})

local box = lib.zones.box({
    coords = vec3(442.5363, -1017.666, 28.65637),
    size = vec3(1, 1, 1),
    rotation = 45,
    debug = true,
    inside = inside,
    onEnter = onEnter,
    onExit = onExit
})
import { Zone } from "@overextended/ox_lib";
import { Vector2, Vector3 } from "@overextended/core/vector";

function onEnter(this: Zone) {
  console.log(`entered ${this.id}`)
}

function onExit(this: Zone) {
  console.log(`exited ${this.id}`)
}

function inside(this: Zone) {
  console.log(`inside ${this.id}`)
}

const shouldDraw = true;

Zone.Prism([
  new Vector2(413.8, -1026.1),
  new Vector2(411.6, -1023.1),
  new Vector2(412.2, -1018.0),
  new Vector2(417.2, -1016.3),
  new Vector2(422.3, -1020.0),
  new Vector2(426.8, -1015.9),
  new Vector2(431.8, -1013.0),
  new Vector2(437.3, -1018.4),
  new Vector2(432.4, -1027.2),
  new Vector2(424.7, -1023.5),
  new Vector2(420.0, -1030.2),
  new Vector2(409.8, -1028.4)
], 2, 29)

Zone.Sphere(new Vector3(442.5363, -1017.666, 28.65637), 1)

Zone.Cuboid(new Vector3(442.5363, -1017.666, 28.65637), 1, 1, 1)

Zone.map.forEach((zone) => {
  zone.inside = inside;
  zone.onEnter = onEnter;
  zone.onExit = onExit;
  zone.shouldDraw = shouldDraw;
})

Zone creation script

You can use our builtin zone-creator with /zone - with poly, box or sphere as an argument.
Available controls will be displayed on the right side.

Zones will be saved to ox_lib/created_zones.lua with your chosen format.

```lua
local poly = lib.zones.poly({
    name = poly,
    points = {
        vec(447.9, -998.8, 25.8),
        vec(450.3, -998.2, 25.8),
        vec(449.9, -995.5, 25.8),
        vec(447.2, -995.6, 25.8),
        vec(446.3, -997.9, 25.8),
    },
    thickness = 2,
})
```


```lua
{
    name = poly,
    points = {
        vec(447.9, -998.8, 25.8),
        vec(450.3, -998.2, 25.8),
        vec(449.9, -995.5, 25.8),
        vec(447.2, -995.6, 25.8),
        vec(446.3, -997.9, 25.8),
    },
    thickness = 2,
},
```


```lua
exports.ox_target:addPolyZone({
    name = poly,
    points = {
        vec(447.9, -998.8, 25.8),
        vec(450.3, -998.2, 25.8),
        vec(449.9, -995.5, 25.8),
        vec(447.2, -995.6, 25.8),
        vec(446.3, -997.9, 25.8),
    },
    thickness = 2,
})
```
Back to documentation