skinchanger
skinchanger applies and reads ESX Legacy ped appearance on the client. All exports, events, skin keys and component config for freemode peds.
skinchanger is the client-only ESX Legacy resource that applies appearance values (heritage, face features, hair, overlays, clothes, props) to the mp_m_freemode_01 and mp_f_freemode_01 peds and reads them back. It does not save anything; esx_skin handles the UI and the database.
Overview
| Resource | skinchanger |
| Version | 1.16.3 (fxmanifest, ships with ESX Legacy 1.16.4) |
| Side | Client only |
| Dependencies | es_extended (locale file only) |
| Used by | esx_skin, esx_multicharacter, job and shop addons |
Skin table
A skin is a flat table of component names and integers. sex is required: 0 is male, 1 is female. Keys you omit keep their current value.
| Group | Keys |
|---|---|
| Model | sex |
| Heritage | mom, dad, grandparents, face_md_weight, skin_md_weight, face_g_weight |
| Face features | nose_1-nose_6, cheeks_1-cheeks_3, lip_thickness, jaw_1, jaw_2, chin_1-chin_4, neck_thickness, eye_color, eye_squint |
| Hair | hair_1, hair_2, hair_color_1, hair_color_2 |
| Clothes | tshirt_1/2, torso_1/2, decals_1/2, arms, arms_2, pants_1/2, shoes_1/2, mask_1/2, bproof_1/2, chain_1/2, bags_1/2 |
| Props | helmet_1/2, glasses_1/2, watches_1/2, bracelets_1/2, ears_1/2 |
| Overlays | eyebrows_1-eyebrows_6, beard_1-beard_4, makeup_1-makeup_4, lipstick_1-lipstick_4, chest_1-chest_3, bodyb_1-bodyb_4, age_1/2, blemishes_1/2, blush_1-blush_3, complexion_1/2, sun_1/2, moles_1/2 |
For props, -1 removes the item (for example helmet_1 = -1).
Old examples use face and skin keys. They no longer exist; use mom, dad and the *_md_weight blend keys instead.
Configuration
| Key | Default | Description |
|---|---|---|
Config.Locale | GetConvar("esx:locale", "en") | Language of component labels. |
Config.Components | 98 entries | Ordered list of editable components. esx_skin builds its menu from it. |
Each entry in Config.Components has these fields:
| Field | Type | Description |
|---|---|---|
name | string | Skin key, for example "torso_1". |
label | string | Translated menu label. |
value | number | Default value used at startup. |
min | number | Minimum value. |
max | number | function(ped, character) | Maximum value, or a function that reads drawable or texture counts from the ped. |
zoomOffset, camOffset | number | Camera position in the esx_skin editor. |
textureof | string | Optional. Marks a texture slider that depends on another component (for example hair_2 depends on hair_1). |
componentId | number | Optional. GTA component or prop index for clothing entries. |
Exports
All exports are client side.
GetSkin
local skin = exports.skinchanger:GetSkin()Returns the current skin table with every component name.
LoadSkin
local ok = exports.skinchanger:LoadSkin(skin)| Name | Type | Description |
|---|---|---|
skin | table | Skin table with sex = 0 or sex = 1. |
Returns false if the skin is invalid. When sex changes, the freemode model is swapped first and the skin is applied afterwards.
LoadClothes
local ok = exports.skinchanger:LoadClothes(playerSkin, clothesSkin)| Name | Type | Description |
|---|---|---|
playerSkin | table | The player's base skin (must contain sex). |
clothesSkin | table | Clothing values to put on top. Face, heritage, hair and overlay (beard, makeup, eyebrows, ...) keys in this table are ignored. |
-- put on the job uniform without touching face or hair
xLib.callback('esx_skin:getPlayerSkin', false, function(skin, jobSkin)
local uniform = skin.sex == 0 and jobSkin.skin_male or jobSkin.skin_female
exports.skinchanger:LoadClothes(skin, uniform)
end)Change
exports.skinchanger:Change(key, value)| Name | Type | Description |
|---|---|---|
key | string | Component name. |
value | number | New value. Changing sex reloads the model. |
GetData
local components, maxVals = exports.skinchanger:GetData(noMax)Returns Config.Components with current values filled in, plus a table of maximum values per component. Pass true as noMax to skip the max calculation.
GetMaxVals
local maxVals = exports.skinchanger:GetMaxVals()Returns { [componentName] = max } for the current ped.
Events
| Event | Type | Arguments | Description |
|---|---|---|---|
skinchanger:loadSkin | Net event | skin, cb? | Same as LoadSkin. cb only works when triggered locally. |
skinchanger:loadClothes | Net event | playerSkin, clothesSkin | Same as LoadClothes. |
skinchanger:getSkin | Local event | cb(skin) | Returns the current skin. |
skinchanger:getData | Local event | cb(components, maxVals) | Same as GetData. |
skinchanger:change | Local event | key, value | Same as Change. |
skinchanger:loadDefaultModel | Local event | isMale, cb? | Sets mp_m_freemode_01 (true) or mp_f_freemode_01 (false). |
skinchanger:modelLoaded | Local event | none | Re-applies a pending skin after a model change. |
TriggerEvent('skinchanger:loadDefaultModel', true, function()
TriggerEvent('skinchanger:loadSkin', { sex = 0, hair_1 = 4, hair_color_1 = 2 })
end)
TriggerEvent('skinchanger:getSkin', function(skin)
print(json.encode(skin))
end)Because skinchanger:loadSkin and skinchanger:loadClothes are net events, the server can push a skin:
TriggerClientEvent('skinchanger:loadSkin', playerId, skin)Common issues
- Skin not applied. The table has no valid
sex. Always includesex = 0orsex = 1. - Changes are lost after relog. skinchanger only changes the ped locally. Save through esx_skin exports on the server.
- Callback of
LoadSkinexport never runs. The export does not accept a callback. Use theskinchanger:loadSkinevent with a callback instead. - Custom component not saved. Add new components to both
Config.Componentshere andConfig.SkinFieldsin esx_skin.
Related
Frequently asked questions
Independent documentation
Last updated on
esx_skin
esx_skin is the ESX Legacy character creator and appearance saver. Server exports, client menu events, config keys, the /skin command and save errors explained.
esx_textui
esx_textui reference for ESX Legacy. Show a persistent help prompt like "Press E to open" with ESX.TextUI and ESX.HideUI, types, events and pitfalls.