FiveM Docs
Core Resources

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

Resourceskinchanger
Version1.16.3 (fxmanifest, ships with ESX Legacy 1.16.4)
SideClient only
Dependencieses_extended (locale file only)
Used byesx_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.

GroupKeys
Modelsex
Heritagemom, dad, grandparents, face_md_weight, skin_md_weight, face_g_weight
Face featuresnose_1-nose_6, cheeks_1-cheeks_3, lip_thickness, jaw_1, jaw_2, chin_1-chin_4, neck_thickness, eye_color, eye_squint
Hairhair_1, hair_2, hair_color_1, hair_color_2
Clothestshirt_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
Propshelmet_1/2, glasses_1/2, watches_1/2, bracelets_1/2, ears_1/2
Overlayseyebrows_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

KeyDefaultDescription
Config.LocaleGetConvar("esx:locale", "en")Language of component labels.
Config.Components98 entriesOrdered list of editable components. esx_skin builds its menu from it.

Each entry in Config.Components has these fields:

FieldTypeDescription
namestringSkin key, for example "torso_1".
labelstringTranslated menu label.
valuenumberDefault value used at startup.
minnumberMinimum value.
maxnumber | function(ped, character)Maximum value, or a function that reads drawable or texture counts from the ped.
zoomOffset, camOffsetnumberCamera position in the esx_skin editor.
textureofstringOptional. Marks a texture slider that depends on another component (for example hair_2 depends on hair_1).
componentIdnumberOptional. 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)
NameTypeDescription
skintableSkin 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)
NameTypeDescription
playerSkintableThe player's base skin (must contain sex).
clothesSkintableClothing values to put on top. Face, heritage, hair and overlay (beard, makeup, eyebrows, ...) keys in this table are ignored.
client/main.lua
-- 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)
NameTypeDescription
keystringComponent name.
valuenumberNew 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

EventTypeArgumentsDescription
skinchanger:loadSkinNet eventskin, cb?Same as LoadSkin. cb only works when triggered locally.
skinchanger:loadClothesNet eventplayerSkin, clothesSkinSame as LoadClothes.
skinchanger:getSkinLocal eventcb(skin)Returns the current skin.
skinchanger:getDataLocal eventcb(components, maxVals)Same as GetData.
skinchanger:changeLocal eventkey, valueSame as Change.
skinchanger:loadDefaultModelLocal eventisMale, cb?Sets mp_m_freemode_01 (true) or mp_f_freemode_01 (false).
skinchanger:modelLoadedLocal eventnoneRe-applies a pending skin after a model change.
client/main.lua
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:

server/main.lua
TriggerClientEvent('skinchanger:loadSkin', playerId, skin)

Common issues

  • Skin not applied. The table has no valid sex. Always include sex = 0 or sex = 1.
  • Changes are lost after relog. skinchanger only changes the ped locally. Save through esx_skin exports on the server.
  • Callback of LoadSkin export never runs. The export does not accept a callback. Use the skinchanger:loadSkin event with a callback instead.
  • Custom component not saved. Add new components to both Config.Components here and Config.SkinFields in esx_skin.

Frequently asked questions

Independent documentation

esx-fivem.com is a community project and is not affiliated with the ESX Framework team. Facts on this page were checked against the upstream source. Official resources: docs.esx-framework.org and github.com/esx-framework.
Edit on GitHub

Last updated on

On this page