ox_lib — Notifiche, Menu, Progress Bar
INFO
ox_lib è la libreria UI di Overextended. Fornisce notifiche, menu contestuali, progress bar, input dialog e molto altro.
| Obiettivo | Dettagli |
|---|---|
| Cosa imparerai | • Usare notifiche, progress bar e menu contestuali • Creare input dialog e text UI • Integrare ox_lib con ESX e ox_inventory |
| Prerequisiti | • ox_lib installato e avviato prima della risorsa • Conoscenza base FiveM events |
1. Setup
ox_lib deve essere avviato PRIMA della tua risorsa:
# server.cfg
ensure ox_lib
ensure es_extended
ensure ox_inventory
ensure tua_risorsa
Nella tua risorsa:
-- fxmanifest.lua
shared_scripts {
'@ox_lib/init.lua', -- Importa tutte le funzioni ox_lib
'config.lua'
}2. Notifiche
Base
lib.notify({
title = 'Titolo',
description = 'Testo della notifica',
type = 'success' -- 'success', 'error', 'info', 'warning'
})Con Durata Personalizzata
lib.notify({
title = 'Arma Acquistata',
description = 'M4A1 Tactical - €5,000',
type = 'success',
duration = 5000, -- 5 secondi (default: 3000)
position = 'top-right', -- 'top-right', 'top-left', 'bottom-right', 'bottom-left'
})Esempi Pratici
-- Acquisto riuscito
lib.notify({
title = 'Acquisto',
description = 'Hai comprato la M4A1 Tactical',
type = 'success'
})
-- Errore
lib.notify({
title = 'Errore',
description = 'Non hai abbastanza denaro',
type = 'error'
})
-- Informazione
lib.notify({
title = 'Informazione',
description = 'Premi E per interagire',
type = 'info'
})3. Progress Bar
Utile per azioni che richiedono tempo (crafting, riparazione, ricerca):
WARNING
I dizionari di animazione (
anim.dict) devono esistere in GTA V. Usa animazioni native esistenti o testale prima. Un dict inesistente blocca la progress bar senza errori visibili.
Base
lib.progressBar({
duration = 5000, -- 5 secondi
label = 'Crafting in corso...',
useWhileDead = false,
canCancel = true, -- Il giocatore può annullare
disable = {
move = true,
car = true,
combat = true,
},
anim = {
dict = 'mini@repair',
clip = 'fixing_a_ped',
},
})
-- Dopo il progress, esegui il codice
print('Crafting completato!')Con Controllo di Annullamento
local success = lib.progressBar({
duration = 10000,
label = 'Riparazione veicolo in corso...',
useWhileDead = false,
canCancel = true,
disable = { move = true, car = true },
anim = { dict = 'mini@repair', clip = 'fixing_a_ped' },
})
if success then
-- Non annullato
TriggerServerEvent('myresource:finishRepair')
lib.notify({
title = 'Riparazione',
description = 'Veicolo riparato con successo!',
type = 'success'
})
else
-- Annullato
lib.notify({
title = 'Riparazione',
description = 'Riparazione annullata',
type = 'info'
})
endEsempio: Crafting Arma
RegisterNetEvent('myresource:craftWeapon')
AddEventHandler('myresource:craftWeapon', function()
-- Verifica che il giocatore abbia i materiali (server-side)
local hasMaterials = lib.callback.await('myresource:checkCraftMaterials')
if not hasMaterials then
lib.notify({
title = 'Crafting',
description = 'Materiali insufficienti',
type = 'error'
})
return
end
-- Avvia crafting
local success = lib.progressBar({
duration = 15000, -- 15 secondi
label = 'Creazione M4A1 in corso...',
canCancel = true,
disable = { move = true, car = true, combat = true },
anim = {
dict = 'amb@prop_human_bum_shopping_cart@male@idle_a',
clip = 'idle_c',
},
})
if success then
TriggerServerEvent('myresource:craftComplete')
end
end)NOTE
Per verificare i materiali usa
lib.callback(clientlib.callback.await('nome', args)→ serverlib.callback.register('nome', function(source, ...)). È il pattern moderno al posto diTriggerServerCallbackdi ESX, ed è già integrato con ox_lib.
4. Menu Contestuali (Context Menu)
Menu Semplice
lib.registerContext({
id = 'weapon_menu',
title = 'Armeria',
options = {
{
title = 'M4A1 Tactical',
description = 'Fucile d\'assalto - €5,000',
icon = 'fa-solid fa-gun',
onSelect = function()
TriggerServerEvent('myresource:buyWeapon', 'WEAPON_M4A1_CUSTOM')
end
},
{
title = 'Munizioni Fucile',
description = '50 proiettili 5.56mm - €100',
icon = 'fa-solid fa-bullseye',
onSelect = function()
TriggerServerEvent('myresource:buyAmmo', 'ammo-rifle', 50)
end
},
{
title = 'Esci',
icon = 'fa-solid fa-xmark',
onSelect = function()
-- Chiude il menu
end
}
}
})
lib.showContext('weapon_menu')Menu con Sotto-Menu (Menu Annidati)
-- Menu principale
lib.registerContext({
id = 'main_menu',
title = 'Menu Principale',
options = {
{
title = 'Armi',
icon = 'fa-solid fa-gun',
menu = 'weapons_menu', -- Apre un altro menu
},
{
title = 'Veicoli',
icon = 'fa-solid fa-car',
menu = 'vehicles_menu',
},
{
title = 'Outfit',
icon = 'fa-solid fa-shirt',
menu = 'outfit_menu',
},
}
})
-- Sotto-menu Armi
lib.registerContext({
id = 'weapons_menu',
title = 'Armi',
options = {
{
title = 'M4A1 Tactical',
description = 'Prezzo: €5,000',
onSelect = function()
TriggerServerEvent('myresource:buyWeapon')
end
},
{
title = 'Indietro',
icon = 'fa-solid fa-arrow-left',
menu = 'main_menu', -- Torna al menu principale
}
}
})TIP
Per menu con molte opzioni, usa la proprietà
menunei singoli option per creare sottomenu annidati. Ogni menu va registrato conlib.registerContext()prima di essere mostrato.
5. Input Dialog
Testo
local input = lib.inputDialog('Acquista Munizioni', {
{ type = 'number', label = 'Quantità', default = 50, min = 1, max = 500 },
{ type = 'select', label = 'Tipo', options = { '5.56mm', '9mm', '12 Gauge' } }
})
if input then
local quantity = input[1]
local ammoType = input[2]
TriggerServerEvent('myresource:buyAmmo', ammoType, quantity)
endEsempio: Deposito Denaro
local input = lib.inputDialog('Banca', {
{ type = 'number', label = 'Importo da depositare', icon = 'fa-solid fa-money-bill' }
})
if input then
local amount = tonumber(input[1])
if amount and amount > 0 then
TriggerServerEvent('myresource:depositMoney', amount)
end
end6. Altri Utility
Text UI (Testo a Schermo)
-- Mostra
lib.showTextUI('[E] - Interagisci', {
position = 'bottom-center',
icon = 'fa-solid fa-hand-pointer',
})
-- Nascondi
lib.hideTextUI()Telefono/Distanza
local dist = #(GetEntityCoords(PlayerPedId()) - vector3(250.0, -150.0, 30.0))
if dist < 50.0 then
-- Vicino al negozio
endTIP
Prossimo passo: 08 - Esempio Completo
Torna alla: Indice Generale