Vestiti e Skin con ESX
INFO
Integrare vestiti custom in ESX significa renderli acquistabili nei negozi di abbigliamento e applicabili con il sistema skin di ESX.
| Obiettivo | Dettagli |
|---|---|
| Cosa imparerai | • Come funziona il sistema skin di ESX • Aggiungere vestiti al negozio con ox_inventory • Usare ox_lib per menu outfit e salvataggio |
| Prerequisiti | • ESX con modulo skin attivo • ox_inventory configurato • Conoscenza componenti ped GTA V |
1. Sistema Skin di ESX
ESX gestisce l’outfit del giocatore tramite eventi skin. Di default usa esx_skin o esx_clothes (deprecato) o si integra con sistemi come illenium-appearance.
Come Funziona
ESX salva l'outfit così:
┌─────────────────────────┐
│ Giocatore nel DB │
│ skin = JSON string │
│ { │
│ "tshirt_1": 0, │ ← Drawable ID
│ "tshirt_2": 0, │ ← Texture ID
│ "pants_1": 0, │
│ "pants_2": 0, │
│ "shoes_1": 0, │
│ ... │
│ } │
└─────────────────────────┘
I campi seguono la nomenclatura di esx_skin (collegata ai componenti GTA V):
| Campo ESX | Component GTA V | Descrizione |
|---|---|---|
mask_1 | 1 | Maschera |
hair_1 | 2 | Capelli |
arms_1 | 3 | Torso + braccia (maglie, camicie) |
pants_1 | 4 | Gambe |
bags_1 | 5 | Borsa / zaino |
shoes_1 | 6 | Scarpe |
chain_1 | 7 | Collane, catene |
tshirt_1 | 8 | Undershirt (sottocamicia) |
vest_1 | 9 | Gilet / giubbotto antiproiettile |
decals_1 | 10 | Decals / loghi |
torso_1 | 11 | Giacca esterna |
helmet_1 | Prop 0 | Cappello / elmetto |
glasses_1 | Prop 1 | Occhiali |
WARNING
Tabella esx_skin reale:
tshirtè l’undershirt (component 8),torsoè la giacca esterna (component 11),armsè torso+braccia (component 3). Molte guide online invertono questi ID. Coerente con la tabella standard freemode nei moduli Ped Custom e Vestiti EUP.
2. Aggiungere Vestiti Custom al Negozio
Usando shop_ped_apparel.meta
TIP
Vedi shop_ped_apparel.meta — questo file registra i vestiti nei negozi nativi di GTA V.
Usando ox_inventory come negozio vestiti
-- ox_inventory/data/shops.lua
return {
['clothes_shop'] = {
name = 'Negozio Abbigliamento',
blip = { id = 73, colour = 2, scale = 0.7 },
targets = {
{
loc = vec3(80.0, -1400.0, 29.0),
length = 1.5, width = 1.5, heading = 0,
minZ = 28.0, maxZ = 30.0,
distance = 2.5,
}
},
inventory = {
-- Ogni item è un "capo" che il giocatore compra
{ name = 'police_shirt', price = 200 },
{ name = 'police_pants', price = 150 },
{ name = 'police_hat', price = 100 },
}
}
}Poi, all’uso dell’item, cambi l’outfit:
WARNING
I component ID (3 = torso, 4 = gambe, 6 = scarpe) sono specifici di GTA V. Usare l’ID sbagliato non avrà effetto o applicherà il componente errato. Verifica sempre con la tabella nella sezione 1.
-- client.lua
-- Quando il giocatore usa "police_shirt" dall'inventario
RegisterNetEvent('myresource:applyClothing')
AddEventHandler('myresource:applyClothing', function(itemName)
local playerPed = PlayerPedId()
if itemName == 'police_shirt' then
SetPedComponentVariation(playerPed, 3, 0, 0, 0) -- Component 3, Drawable 0
elseif itemName == 'police_pants' then
SetPedComponentVariation(playerPed, 4, 0, 0, 0)
elseif itemName == 'police_hat' then
SetPedPropIndex(playerPed, 0, 0, 0, true)
end
end)3. Usare ox_lib per un Menu Vestiti
NOTE
La callback
esx_skin:getPlayerSkinvaria tra versioni/moduli skin. Il pattern più robusto è leggere lo skin dal server (dove ESX lo carica al login) oppure usare l’evento standardesx_skin:openSaveableMenu. Gli esempi sotto sono didattici: verifica i nomi esatti nella tua versione diesx_skin/illenium-appearance.
-- client.lua
local ESX = exports['es_extended']:getSharedObject()
RegisterCommand('outfit', function()
lib.registerContext({
id = 'clothing_menu',
title = 'Outfit',
options = {
{
title = 'Uniforme Polizia',
description = 'Applica uniforme di servizio',
onSelect = function()
TriggerEvent('myresource:setUniform', 'police')
end
},
{
title = 'Divisa Operativa',
description = 'Applica divisa tattica',
onSelect = function()
TriggerEvent('myresource:setUniform', 'tactical')
end
},
{
title = 'Azzera Outfit',
description = 'Torna ai vestiti base',
onSelect = function()
TriggerEvent('myresource:resetClothes')
end
}
}
})
lib.showContext('clothing_menu')
end, false)Applicare un Outfit Preimpostato
-- client.lua
RegisterNetEvent('myresource:setUniform')
AddEventHandler('myresource:setUniform', function(type)
local playerPed = PlayerPedId()
if type == 'police' then
-- Applica ogni componente uno per uno
SetPedComponentVariation(playerPed, 3, 0, 0, 0) -- Torso+braccia
SetPedComponentVariation(playerPed, 4, 0, 0, 0) -- Gambe
SetPedComponentVariation(playerPed, 6, 0, 0, 0) -- Scarpe
SetPedPropIndex(playerPed, 0, 0, 0, true) -- Cappello
SetPedPropIndex(playerPed, 1, 0, 0, true) -- Occhiali
elseif type == 'tactical' then
SetPedComponentVariation(playerPed, 3, 1, 0, 0) -- Torso alternativo
SetPedComponentVariation(playerPed, 4, 1, 0, 0) -- Pantaloni tattici
SetPedComponentVariation(playerPed, 6, 1, 0, 0) -- Stivali
SetPedPropIndex(playerPed, 0, 0, 1, true) -- Berretto
end
-- Notifica locale
lib.notify({
title = 'Outfit',
description = 'Uniforme applicata!',
type = 'success'
})
end)WARNING
I componenti qui (3 = torso, 4 = gambe, 6 = scarpe) sono quelli nativi
SetPedComponentVariation(numerazione freemode), non i campi esx_skin. Nativi e campi ESX usano numerazioni diverse: vedi la tabella in sezione 1.
4. Integrazione con illenium-appearance
Se usi illenium-appearance (molto comune con ESX), i vestiti custom vengono caricati dai drawable del tuo pack e mostrati automaticamente nel menu. Non esiste una config Config.CustomClothing standard: la struttura esatta cambia tra versioni.
-- configuration/clothing.lua (esempio indicativo — controlla la tua versione)
-- Ogni voce lega una parte del corpo (drawable) a un outfit con nome
-- e a un insieme di componenti nativi da applicare.
Config.CustomOutfits = {
['police'] = {
label = 'Uniforme Polizia',
components = {
[3] = { drawable = 0, texture = 0 }, -- Torso+braccia
[4] = { drawable = 0, texture = 0 }, -- Gambe
[6] = { drawable = 0, texture = 0 }, -- Scarpe
[8] = { drawable = 0, texture = 0 }, -- Undershirt
},
props = {
[0] = { drawable = 0, texture = 0 }, -- Cappello
},
},
['tactical'] = {
label = 'Divisa Operativa',
components = {
[3] = { drawable = 1, texture = 0 },
[4] = { drawable = 1, texture = 0 },
[6] = { drawable = 1, texture = 0 },
},
props = {},
},
}WARNING
Non esiste
Config.CustomClothingnello standard di illenium-appearance. Se cerchi online e trovi nomi di config “che non matchano”, è perché molti tutorial usano risorse fork o versioni personalizzate. Verifica sempre contro il repo della versione che usi.
5. Salvare l’Outfit
Quando il giocatore cambia vestito, aggiorna lo skin salvato in ESX tramite callback tua (non inventare nomi di callback esistenti):
-- client.lua
RegisterNetEvent('myresource:saveCurrentOutfit')
AddEventHandler('myresource:saveCurrentOutfit', function(name)
local playerPed = PlayerPedId()
local outfit = {
name = name,
components = {}
}
-- Leggi tutti i componenti
for i = 0, 11 do
local drawable, texture = GetPedDrawableVariation(playerPed, i), GetPedTextureVariation(playerPed, i)
outfit.components[i] = { drawable = drawable, texture = texture }
end
-- Chiama una callback che registri tu (es. esx_skin:setPlayerSkin o una tua)
ESX.TriggerServerCallback('myresource:saveOutfit', function(success)
if success then
lib.notify({
title = 'Outfit Salvato',
description = name .. ' salvato con successo!',
type = 'success'
})
end
end, outfit)
end)-- server.lua
ESX.RegisterServerCallback('myresource:saveOutfit', function(source, cb, outfit)
local xPlayer = ESX.GetPlayerFromId(source)
-- Salva la skin nella tabella users (colonna skin) come JSON
MySQL.update('UPDATE users SET skin = ? WHERE identifier = ?', {
json.encode(outfit.components),
xPlayer.identifier
}, function()
cb(true)
end)
end)TIP
Con
illenium-appearanceil salvataggio è già gestito: i vestiti custom vanno aggiunti alla sua config e il menu salva da solo. Non serve replicare il codice qui sopra se usi quel modulo.
TIP
Prossimo passo: 06 - ox_target e Interazioni
Torna alla: Indice Generale