ox_target e Interazioni
INFO
ox_target permette di creare punti di interazione nel mondo. Perfetto per negozi, veicoli, NPC e oggetti custom.
| Obiettivo | Dettagli |
|---|---|
| Cosa imparerai | • Creare zone di interazione (box, sphere, entity) • Integrare ox_target con veicoli e NPC • Usare opzioni avanzate come filtri per job/item |
| Prerequisiti | • ox_target installato e avviato • Conoscenza base FiveM events • ox_lib per notifiche |
Cos’è ox_target
ox_target sostituisce i vecchi sistemi di interazione (es. drawtext, 3dtext, qtarget). Mostra un menu contestuale quando il giocatore punta e interagisce con oggetti/zona nel mondo.
Tipi di Zone
| Tipo | Descrizione | Quando Usarlo |
|---|---|---|
addBoxZone | Zona rettangolare | Negozi, porte, ingressi |
addSphereZone | Zona sferica | Aree circolari |
addCircleZone | Zona cerchio | Raggio intorno a un punto |
addEntityZone | Entità GTA V | Veicoli, ped, oggetti |
addModelZone | Tutte le entità di un modello | Es. tutte le sedie |
addTargetBone | Osso specifico | Porte veicolo, ruote |
1. Zona Base (Box)
-- client.lua
CreateThread(function()
exports.ox_target:addBoxZone({
coords = vector3(250.0, -150.0, 29.5), -- Centro zona
size = vec3(2.0, 2.0, 2.0), -- Larghezza, profondità, altezza
rotation = 0, -- Rotazione
debug = Config.Debug, -- Mostra il box (debug)
options = {
{
name = 'open_shop', -- ID univoco
event = 'myresource:openShop', -- Evento da triggerare
icon = 'fa-solid fa-shop', -- Icona FontAwesome
label = 'Apri Negozio', -- Testo
canInteract = function(entity, distance, coords, name, bone)
return true -- Condizione per mostrare
end,
distance = 2.5, -- Distanza di interazione
items = nil, -- Item richiesti (es. {'key'})
job = nil, -- Job richiesto (es. 'police')
}
}
})
end)2. Interazione con Veicoli
WARNING
addModelva chiamato una sola volta (all’avvio della risorsa). ox_target applica automaticamente le opzioni a tutti i veicoli di quel modello nel mondo. Chiamarlo dentro unwhile trueregistra le stesse opzioni migliaia di volte e degrada il server.
-- client.lua
CreateThread(function()
-- Una singola chiamata: vale per ogni veicolo modello 'charger20'
-- che appare (o apparirà) nel mondo.
exports.ox_target:addModel('charger20', {
options = {
{
name = 'lock_vehicle',
icon = 'fa-solid fa-lock',
label = 'Blocca/Sblocca',
onSelect = function(data)
local plate = GetVehicleNumberPlateText(data.entity)
TriggerServerEvent('myresource:toggleDoor', plate)
end,
distance = 3.0,
canInteract = function(entity, distance)
-- Mostra l'opzione solo se il giocatore ha la chiave di quel veicolo
local plate = GetVehicleNumberPlateText(entity)
local count = exports.ox_inventory:Search(nil, 'count', 'vehiclekey', { plate = plate })
return count > 0
end
},
{
name = 'check_vehicle',
icon = 'fa-solid fa-info',
label = 'Controlla Veicolo',
event = 'myresource:checkVehicle',
job = 'police', -- Solo polizia
distance = 3.0,
}
}
})
end)NOTE
La firma corretta di
Searchin ox_inventory èexports.ox_inventory:Search(inv, 'count', item, metadata)— sul client si passanilcome inventario (il giocatore locale) e'count'per ricevere il numero di item. Gli eventi di interazione si collegano conevent(TriggerServerEvent) oppureonSelect(callback locale).
3. Interazione con Entità (Entity)
-- client.lua
-- Per un oggetto specifico nel mondo (es. un banco da lavoro spawnato)
CreateThread(function()
-- Prima spawna l'oggetto
local model = GetHashKey('prop_toolchest_01')
RequestModel(model)
while not HasModelLoaded(model) do Wait(100) end
local workbench = CreateObjectNoOffset(model, 300.0, -100.0, 29.5, true, false, false)
SetEntityHeading(workbench, 0.0)
FreezeEntityPosition(workbench, true)
-- Poi aggiungi interazione (entity handle, non il nome)
exports.ox_target:addLocalEntity(workbench, {
options = {
{
name = 'open_crafting',
icon = 'fa-solid fa-screwdriver-wrench',
label = 'Apriti Banco da Lavoro',
event = 'myresource:openCrafting',
distance = 2.0,
}
}
})
end)4. Interazione con Ped (NPC)
INFO
Le entità spawnate (ped, oggetti) persistono nel mondo finché non vengono cancellate con
DeleteEntity(). Usaox_target:removeLocalEntity()quando rimuovi l’entità per pulire anche le interazioni.
-- client.lua
CreateThread(function()
-- Spawna un NPC
local model = GetHashKey('s_m_y_cop_01')
RequestModel(model)
while not HasModelLoaded(model) do Wait(100) end
local npc = CreatePed(1, model, 250.0, -150.0, 30.0, 180.0, true, false)
SetEntityInvincible(npc, true)
FreezeEntityPosition(npc, true)
TaskStartScenarioInPlace(npc, 'WORLD_HUMAN_CLIPBOARD', 0, true)
-- Aggiungi interazione al ped
exports.ox_target:addEntity(npc, {
options = {
{
name = 'talk_to_armorer',
icon = 'fa-solid fa-gun',
label = 'Parla con l\'Armaiolo',
event = 'myresource:openWeaponShop',
distance = 2.5,
}
}
})
end)5. Eventi Lato Server
-- client.lua
RegisterNetEvent('myresource:openShop')
AddEventHandler('myresource:openShop', function()
-- Apri lo shop registrato (vedi file 03: data/shops.lua o RegisterShop)
exports.ox_inventory:openInventory('shop', {
type = 'weapon_shop_basic',
})
end)NOTE
openInventory('shop', { type = ... })apre un negozio registrato (indata/shops.luao tramiteexports.ox_inventory:RegisterShop). Non si passanoitems/slots/labelinline: quelle proprietà vengono dal negozio registrato. Vedi Armi Custom con ESX.
-- server.lua
RegisterNetEvent('myresource:buyItemServer')
AddEventHandler('myresource:buyItemServer', function(item, price)
local xPlayer = ESX.GetPlayerFromId(source)
-- MAI fidarsi del prezzo inviato dal client: ricalcola dal config
if type(item) ~= 'string' then return end
local shopItem = Config.ShopItems[item]
if not shopItem then return end
price = shopItem.price
if xPlayer.getAccount('money').money >= price then
xPlayer.removeAccountMoney('money', price)
xPlayer.addInventoryItem(item, 1)
exports.ox_lib:notify(source, {
title = 'Acquisto',
description = item .. ' acquistato!',
type = 'success'
})
end
end)6. Opzioni Avanzate di ox_target
Opzioni Dinamiche
exports.ox_target:addBoxZone({
coords = vector3(250.0, -150.0, 29.5),
size = vec3(1.0, 1.0, 2.0),
rotation = 0,
options = {
-- Opzione visibile solo se il giocatore ha un item
{
name = 'repair_vehicle',
icon = 'fa-solid fa-wrench',
label = 'Ripara Veicolo',
event = 'myresource:repairVehicle',
items = 'repair_kit', -- Richiede repair_kit nell'inventario
distance = 2.0,
},
-- Opzione visibile solo per un job specifico
{
name = 'impound_vehicle',
icon = 'fa-solid fa-tow-truck',
label = 'Sequestra Veicolo',
event = 'myresource:impoundVehicle',
job = 'police',
distance = 2.0,
},
-- Opzione con funzione personalizzata
{
name = 'custom_action',
icon = 'fa-solid fa-star',
label = 'Azione Custom',
canInteract = function(entity, distance, coords)
local hour = GetClockHours()
return hour >= 9 and hour <= 18 -- Solo in orario ufficio
end,
onSelect = function()
TriggerEvent('myresource:customAction')
end,
distance = 2.0,
}
}
})Rimuovere una Zona
-- Rimuovi una zona specifica
exports.ox_target:removeZone('open_shop')
-- Rimuovi tutte le zone di una risorsa
exports.ox_target:removeLocalEntity(npc)TIP
Prossimo passo: 07 - ox_lib UI
Torna alla: Indice Generale