ox_target addBoxZone, addModel and addLocalEntity: how to add targets

How to add ox_target interactions in FiveM: addBoxZone, addSphereZone, addModel, addLocalEntity and addGlobalVehicle, with options, groups, removal and debug.

You add a target in your script and in game nothing shows up. Or the console says:

text
No such export addBoxZone in resource ox_target

This is the practical guide to ox_target on the client: the zone, model and entity exports, the options you can put on them, and how to remove and debug them.

Make sure ox_target is started first

The exports only exist while ox_target is running, and it needs ox_lib. In server.cfg, start them before your script:

cfg
ensure oxmysql
ensure ox_lib
ensure ox_target

ensure my_script

Also add it to your resource's fxmanifest.lua, so FiveM refuses to start the script without it:

lua
dependency 'ox_target'

All the calls below are client side. Put them in a client file, not a server one.

A box zone

A box zone is a rectangle in the world. It is the right choice for a counter, a door or an ATM:

lua
local zoneId = exports.ox_target:addBoxZone({
    coords = vec3(441.2, -981.9, 30.7),
    size = vec3(1.5, 1.0, 2.0),
    rotation = 90.0,
    debug = false,
    options = {
        {
            name = 'my_script_counter',
            icon = 'fa-solid fa-box',
            label = 'Open the counter',
            distance = 2.0,
            onSelect = function(data)
                print('selected', data.name)
            end,
        },
    },
})

coords is the centre of the box, size is its width, length and height, and rotation turns it around the vertical axis. Keep the returned zoneId if you will remove the zone later.

A sphere zone

A sphere is simpler when you do not care about the shape, only about "near this point":

lua
exports.ox_target:addSphereZone({
    coords = vec3(-1037.5, -2737.9, 20.2),
    radius = 1.5,
    options = {
        {
            name = 'my_script_sphere',
            icon = 'fa-solid fa-hand',
            label = 'Talk',
            onSelect = function()
                print('talking')
            end,
        },
    },
})

Models, entities and vehicles

To target every object, ped or vehicle of a certain model, use addModel. It takes a model name or hash, or a list of them:

lua
exports.ox_target:addModel({ `prop_vend_soda_01`, `prop_vend_soda_02` }, {
    {
        name = 'my_script_vending',
        icon = 'fa-solid fa-bottle-water',
        label = 'Use the machine',
        distance = 1.5,
        onSelect = function(data)
            print('entity', data.entity)
        end,
    },
})

To target one entity you already created on your client, use addLocalEntity:

lua
local ped = CreatePed(4, `a_m_m_business_01`, 441.2, -981.9, 29.7, 90.0, false, true)

exports.ox_target:addLocalEntity(ped, {
    {
        name = 'my_script_ped',
        icon = 'fa-solid fa-comment',
        label = 'Talk to him',
        onSelect = function(data)
            print('talk to', data.entity)
        end,
    },
})

To add an option to every vehicle, use addGlobalVehicle. Other global exports exist for peds, players and objects:

lua
exports.ox_target:addGlobalVehicle({
    {
        name = 'my_script_inspect',
        icon = 'fa-solid fa-magnifying-glass',
        label = 'Inspect vehicle',
        distance = 2.5,
        onSelect = function(data)
            print('vehicle', data.entity)
        end,
    },
})

Tip: addLocalEntity only exists on the client that created the entity. For a networked entity that other players should see the option on, use the networked variant (addEntity) with the entity's network id.

The option fields

Each option is a table. These are the fields you will use most:

Field What it does
name A unique name. Needed to remove the option later.
icon A Font Awesome class, like fa-solid fa-box.
label The text shown to the player.
onSelect Function called when the player picks the option.
distance How close the player must be, in metres.
canInteract Function that returns true to show the option.
groups Job or group needed to see the option.

canInteract receives the entity and the distance, so you can hide an option based on any condition:

lua
{
    name = 'my_script_repair',
    icon = 'fa-solid fa-wrench',
    label = 'Repair',
    distance = 2.0,
    canInteract = function(entity, distance, coords, name, bone)
        return GetVehicleEngineHealth(entity) < 900.0
    end,
    onSelect = function(data)
        print('repair', data.entity)
    end,
}

For jobs, groups takes a name or a table, and works on ESX, QBCore and QBox through ox_target's own framework support:

lua
groups = 'police',
-- or several, optionally with a minimum grade
groups = { police = 0, sheriff = 2 },

Remove zones and options

Zones are removed with the id the call returned:

lua
exports.ox_target:removeZone(zoneId)

Options added to models, entities and global targets are removed by the name you gave them:

lua
exports.ox_target:removeModel({ `prop_vend_soda_01` }, 'my_script_vending')
exports.ox_target:removeLocalEntity(ped, 'my_script_ped')
exports.ox_target:removeGlobalVehicle('my_script_inspect')

Clean up when your resource stops, otherwise a restart can leave duplicates behind:

lua
AddEventHandler('onResourceStop', function(resource)
    if resource ~= GetCurrentResourceName() then return end
    exports.ox_target:removeZone(zoneId)
    exports.ox_target:removeLocalEntity(ped, 'my_script_ped')
end)

Debug a zone that does not show

Set debug = true on the zone. ox_target then draws its shape in the world, so you see at once if the box is in the wrong place, too small, or buried in the floor. The usual causes:

  • The zone is misplaced. The coords are the centre, so a box whose z sits at floor level is half underground. Raise it by half its height.
  • The distance is too small. The player has to be inside distance of the zone to see the option.
  • A check fails. A groups or canInteract that returns false hides the option with no error. Temporarily remove it to test.
  • Two targets are running. If qb-target is started as well, see qb-target vs ox_target.

By default you hold a key (Left Alt) to open the targeting eye, so test with it held down.

Checklist

Symptom Fix
No such export addBoxZone in resource ox_target Start ox_target (and ox_lib) before your script
Option never shows Turn on debug = true, check distance, groups and canInteract
Zone is half underground coords is the centre: raise z by half the box height
Option shows for everyone Add groups or a canInteract check
Duplicates after restarting your script Remove zones and options in onResourceStop
Need to remove one option Give it a name and call the matching remove... export

Quick answers

How do I add an ox_target zone from my own script?

Call exports.ox_target:addBoxZone({ coords = ..., size = ..., rotation = ..., options = { ... } }) on the client. It returns an id that you keep so you can remove the zone later.

How do I show an option only to some jobs?

Use groups on the option, for example groups = 'police', or a table for several jobs. For anything more specific, return true or false from canInteract.

Why does my target not appear?

Usually the player is outside the option's distance, a groups or canInteract check fails, or ox_target is not started before your script. Turn on debug = true on the zone to see its shape.

Scripts that skip this problem

Shop CreatorBuild a shop in under a minute β€” owners, employees, vaults and robberies included.View script β†’Quest CreatorA visual editor for quests and NPC dialogues, built node by node in game.View script β†’Item Creator V2Create usable items with animations, props, effects and more β€” without writing code.View script β†’

Keep reading