Targets & World Interactions

Select one installed target in Config.Installer.target, then choose how its registrations appear through Config.Interaction.replaceTargets.


Cursor targeting

Lua
Config.Installer.target = 'ox_target' -- or 'qb-target'
Config.Interaction.enabled = true
Config.Interaction.replaceTargets = false

Complete installation and the full restart. The target keeps its native registry/gameplay callbacks while Finals provides the cursor UI. Existing registrations normally do not need individual rewrites.

Convert targets to world prompts

Lua
Config.Interaction.replaceTargets = true
Config.Interaction.defaultInteractKey = 'E'
Config.Interaction.maxInteractDistance = 5.0
Config.Interaction.requireLookAt = true
Config.Interaction.requireLos = true

The bridge imports ox_target's registry and replays QB registration mutations. Global/entity/model targets, bones/offsets and zone-center prompts are supported. Cursor UI is suppressed in this mode. A zone prompt uses its center rather than reproducing a cursor ray-hit anywhere inside the zone; tune distance accordingly. Combo zones get member prompts.

For ox_target, fuitargetsync in F8 requests synchronization and reports status. The first bridge installation requires target code to reload. Later Finals restarts can import existing registrations.

Register a world point

Lua
local id = exports.finals_UI:addCoords(vec3(100.0, 200.0, 30.0), {
    name = 'locker', label = 'Open locker', icon = 'box-open', distance = 2.0,
    onSelect = function(data)
        print('Selected locker', data.coordsId)
    end
})
-- Remove from the resource that registered it:
exports.finals_UI:removeCoords(id)

Multiple options first expand the compact prompt. Scroll or use arrows to select. Hold the interaction key for holdTime options. Losing eligibility, range, focus or the registration cancels the hold.

Entities and models

Lua
exports.finals_UI:addLocalEntity(entity, {
    name='search', label='Search', icon='magnifying-glass', distance=2,
    holdTime=1200,
    canInteract=function(target, distance, coords, name)
        return DoesEntityExist(target)
    end,
    onSelect=function(data) print(data.entity) end
})
exports.finals_UI:addModel('prop_till_01', {
    name='register', label='Use register', icon='cash-register', event='myshop:open'
})
exports.finals_UI:removeLocalEntity(entity, 'search')
exports.finals_UI:removeModel('prop_till_01', 'register')
RegistrationRemoval
addCoords(coords, options)removeCoords(id, names?)
addLocalEntity(handleOrArray, options)removeLocalEntity(handles, names?)
addEntity(netIdOrArray, options)removeEntity(netIds, names?)
addModel(modelOrArray, options)removeModel(models, names?)
addGlobalPed/Vehicle/Object/Player(options)removeGlobalPed/Vehicle/Object/Player(names?)

Use disableInteract(true/false) to toggle the local engine. isInteractionActive() reports an active usable prompt. Registrations/removals belong to their caller and are cleaned when it stops.

Options and responses

Options include name, label, icon, distance, holdTime, cooldown, groups, items/anyItem, allowInVehicle, bones, normalized model offset, entity-local offsetAbsolute, menuName/openMenu and canInteract. Choose onSelect, export, event, serverEvent or command as the action. Activity hooks onActive/onInactive/whileActive should not yield or perform slow work.

Responses include entity, coords, coordsId, distance, name/label and owner. Client callbacks use local entity handles; serverEvent converts networked entities to network IDs. Server code must revalidate permissions, distance, inventory and rewards. Client eligibility is presentation, not authorization.

Optional hold anim/prop are supported. Cosmetic hold props are local and removed on completion/cancellation. No separate interaction engine or hologram model resource is required.