en-target is EndCore's "third eye". Players hold Left Alt, look at a ped, another player, a vehicle, an object or a spot in the world, and a short list of options appears beside the reticle. The mouse wheel moves through the list; left-click or E picks an option.
The camera keeps moving while you look, because en-target never takes NUI focus. Vehicles and objects under the reticle get an orange outline (peds are not outlined). Looking is blocked while you are dead, in the pause menu, focused on another NUI, or not logged in to a character.
At a glance
| Depends on | en-core, en-ui |
| Side | Client only (no server scripts) |
| Start after | en-core, en-ui. Start order does not matter for callers using encore.target.* |
| Database tables | None |
| Config files | config/client.lua |
| Key binds | en_target_look, default Left Alt |
How it works
While the look key is held (or toggled on), en-target casts a ray from the camera every Config.tickRate milliseconds. It collects the options that apply to whatever the ray hits:
- Global options for every ped, player, vehicle or object.
- Model options for specific model names or hashes.
- Local entity options for specific entity handles you pass in.
- Sphere zones placed at world coordinates.
Each option is then filtered by its own distance, bones, groups, items and canInteract checks. Only options that pass are shown. When the player picks one, looking stops first and then the action runs.
Options are tracked per registering resource and removed automatically when that resource stops. Deleted local entities are purged every 10 seconds.
Restart safety
If you register through the library wrapper encore.target.*, global, model and zone registrations are remembered and re-applied whenever en-target starts or restarts. Local entity registrations are not remembered across an en-target restart, so register those again when needed.
If en-target is not running, nothing shows. A resource that must keep working without it should fall back to encore.showPrompt. See Target interface.
Configuration
config/client.lua:
| Key | Default | What it does |
|---|---|---|
Config.key | 'LMENU' (Left Alt) | Default look key; players can rebind it in Settings > Key Bindings > FiveM |
Config.toggle | false | true = press to start and stop looking; false = hold |
Config.rayLength | 8.0 | How far the look ray reaches (m). Options still check their own distance |
Config.defaultDistance | 2.0 | Option distance when an option sets none |
Config.tickRate | 50 | Look check interval (ms) |
Config.boneRadius | 1.2 | Max distance from the look point to a listed bone |
Config.debugZones | false | Draw sphere zones within 30 m while looking |
Config.disabledControls | weapon wheel 14-17, 37; attack/aim 24, 25, 257; E 38; melee 140-143, 263, 264 | Controls blocked while looking |
-- config/client.lua: press Alt once to start looking, again to stop
Config.key = 'LMENU'
Config.toggle = true
Config.rayLength = 10.0Option shape
Every export takes one option or a list of options.
{
name = 'my-res:action', -- unique; the same name replaces. Default '<resource>:<label>'
label = 'Do thing',
icon = 'box', -- en-ui icon name
distance = 2.0, -- player-to-look-point distance
bones = { 'boot' }, -- entity bones; nearest within Config.boneRadius
groups = { medic = 2 }, -- see below
items = 'lockpick', -- see below
canInteract = function(entity, distance, coords, name, bone) return true end,
onSelect = function(data) end, -- data = { name, label, entity, coords, distance, zone, bone }
-- used only when onSelect is absent, checked in this order:
event = 'client:event', -- TriggerEvent(event, data)
serverEvent = 'server:event', -- TriggerServerEvent; data.entity becomes a network id (0 if not networked)
command = 'somecommand', -- ExecuteCommand
}| Field | Accepted values |
|---|---|
groups | 'medic', { 'medic', 'police' }, { medic = 2 } (job and minimum grade), 'group' (anyone in a player group), 'group:12' or { ['group:12'] = 2 } (a specific group, optionally with a minimum grade) |
items | 'lockpick', { 'lockpick', 'torch' } (all required), { lockpick = 1, scrap = 3 } (minimum counts) |
canInteract | Runs on every check, so it must return quickly and must not wait |
groups is checked against the player's job name and grade from exports['en-core']:GetPlayerData(), or their player group. items is checked with encore.inventory.getItemCount.
Exports
Client exports on exports['en-target']:
| Export | Arguments | Returns |
|---|---|---|
AddGlobalPed / RemoveGlobalPed | options / names? | Non-player peds |
AddGlobalPlayer / RemoveGlobalPlayer | options / names? | Player peds |
AddGlobalVehicle / RemoveGlobalVehicle | options / names? | |
AddGlobalObject / RemoveGlobalObject | options / names? | |
AddModel / RemoveModel | models, options / models, names? | Model names or hashes |
AddLocalEntity / RemoveLocalEntity | entities, options / entities, names? | Existing entity handles |
AddSphereZone | zone = { name?, coords, radius? (1.5), options, debug? } | Zone name |
RemoveZone | name | |
IsActive | boolean, true while looking | |
Disable | state | true disables and stops looking (cutscenes, cuffs); false re-enables |
IsDisabled | boolean |
Calling a Remove* export with no names clears every option in that list.
encore.target wrapper
Prefer the library wrapper from en-core. It survives en-target restarts (except local entities) and runs onSelect in its own thread inside your resource, so your handler may wait on callbacks or progress bars.
| Function | Notes |
|---|---|
encore.target.addGlobalPed/Vehicle/Object/Player(options) | |
encore.target.removeGlobalPed/Vehicle/Object/Player(names) | |
encore.target.addModel(models, options) / removeModel(models, names) | |
encore.target.addLocalEntity(entity, options) / removeLocalEntity(entity, names) | |
encore.target.addSphereZone(zone) / removeZone(name) | |
encore.target.isAvailable() | Whether en-target is running |
Events
en-target has no events of its own. It stops looking when it receives encore:client:playerUnloaded or encore:client:playerDied.
Examples
A searchable vending machine that needs a lockpick, and a radio tower anyone in a player group can use:
-- client.lua
encore.target.addModel({ 'prop_vend_snack_01', 'prop_vend_soda_01' }, {
name = 'my-scav:vending',
label = 'Search vending machine',
icon = 'search',
distance = 1.8,
items = 'lockpick',
canInteract = function(entity) return not Entity(entity).state.searched end,
onSelect = function(data)
local ok = encore.callback.await('my-scav:search', NetworkGetNetworkIdFromEntity(data.entity))
end,
})
encore.target.addSphereZone({
name = 'my-scav:radio_tower',
coords = vec3(750.2, 1300.5, 360.3),
radius = 1.5,
options = {
{ name = 'my-scav:broadcast', label = 'Use radio', icon = 'radio', groups = 'group', onSelect = function() end },
},
})Turn looking off during a scripted scene:
exports['en-target']:Disable(true)
-- ... scene ...
exports['en-target']:Disable(false)