Zurück zum Blog
Tutorial8 Min. Lesezeit

FiveM-Bekleidungsaddons: Eigene Kollektionen streamen

Binde eigene Kleidung in FiveM ein. Richte Addons ein, verwalte Slots, behebe Konflikte und lerne den Ablauf für exklusive Serverkollektionen kennen.

Agency Scripts

Gründer und leitender Entwickler bei Agency Scripts

Das Kleidungssystem von GTA V verstehen

GTA V verwendet ein komponentenbasiertes Kleidungssystem, bei dem jedes Kleidungsstück ein „Drawable“ innerhalb eines bestimmten Komponenten-Slots ist. Ein Ped hat 12 Komponenten-Slots, vom Kopf (Komponente 0) über die Schuhe (Komponente 6) bis hin zu Taschen und Accessoires. Jeder Komponenten-Slot kann mehrere Drawables enthalten, und jedes Drawable kann verschiedene Texturvarianten haben. Komponente 11 (Oberteile) könnte beispielsweise Drawable 15 (eine Lederjacke) mit den Texturen 0 bis 3 enthalten, die schwarze, braune, rote und weiße Farbvarianten darstellen. Diese Hierarchie aus Komponenten, Drawables und Texturen zu verstehen, ist wichtig, bevor du eigene Kleidung erstellen kannst, denn jedes hinzugefügte Kleidungsstück muss in diese bestehende Struktur passen. Das Multiplayer-Ped-Modell (MP) bringt eine weitere Ebene mit einer eigenen Drawable-Zuordnung mit, die sich von den Spielfiguren im Einzelspielermodus unterscheidet. FiveM-Server verwenden ausschließlich die MP-Freemode-Modelle.

Ressourcenstruktur und Streaming

Benutzerdefinierte Kleidung funktioniert in FiveM über das Streaming-System. Du erstellst eine Resource, die dem Spiel mitteilt, zusätzliche Drawable- und Texturdateien zusammen mit den Assets des Basisspiels zu laden. Die Resource-Struktur folgt strengen Benennungskonventionen, anhand derer die Game-Engine erkennt, zu welchem Ped-Modell, welcher Komponente und welchem Drawable-Index jede Datei gehört. Eine falsche Ordnerstruktur ist der häufigste Grund dafür, dass Kleidung im Spiel nicht angezeigt wird. Deine Resource benötigt eine fxmanifest.lua die die Streaming-Dateien deklariert. Die eigentlichen Kleidungsdaten kommen in ein stream Verzeichnis mit der richtigen Unterordnerstruktur.

-- fxmanifest.lua for a clothing addon
fx_version 'cerulean'
game 'gta5'

-- The resource name matters: it determines load priority
-- Prefix with zzz_ to ensure it loads after base game assets
this_is_a_map 'yes'
lua54 'yes'

-- All streaming assets inside /stream/ are auto-detected
-- No need to list individual files

Der Stream-Ordner folgt einer genau festgelegten Hierarchie. Für Kleidung für männliche MP-Freemode-Peds kommen die Dateien in stream/mp_m_freemode_01_mp_m_[dlcname]/ . Bei weiblichen Peds ersetzt du mp_m durch mp_f. In diesem Ordner platzierst du die YDD-Dateien (Drawable Dictionary), YTD-Dateien (Texture Dictionary) und YMT-Dateien (Metadata). Die Benennungskonvention gibt an, welche Komponente und welchen Drawable-Index jede Datei darstellt. Eine Datei mit dem Namen mp_m_freemode_01_mp_m_mypack_jbib_000_u.ydd ist Drawable 0 für Komponente 11 (jbib = Jacken/Oberteile) beim männlichen Freemode-Ped aus dem DLC-Pack "mypack".

-- Folder structure example
stream/
  mp_m_freemode_01_mp_m_mypack/
    mp_m_freemode_01_mp_m_mypack.ymt          -- metadata file
    mp_m_freemode_01_mp_m_mypack_jbib_000_u.ydd   -- tops drawable 0
    mp_m_freemode_01_mp_m_mypack_jbib_diff_000_a_uni.ytd  -- texture for tops 0
    mp_m_freemode_01_mp_m_mypack_jbib_001_u.ydd   -- tops drawable 1
    mp_m_freemode_01_mp_m_mypack_jbib_diff_001_a_uni.ytd  -- texture for tops 1
    mp_m_freemode_01_mp_m_mypack_lowr_000_u.ydd   -- pants drawable 0
    mp_m_freemode_01_mp_m_mypack_lowr_diff_000_a_uni.ytd  -- texture for pants 0

Komponenten-IDs und Benennungskonventionen

Jede Kleidungskomponente hat eine bestimmte Abkürzung, die bei der Dateibenennung verwendet wird. Diese Abkürzungen solltest du dir unbedingt merken, denn schon ein Tippfehler reicht, damit das Spiel dein Asset nicht findet. Die Komponentenübersicht lautet: head (Komponente 0, keine Kleidung), berd (1, Masken), hair (2), uppr (3, Arme/Handschuhe), lowr (4, Hosen/Beine), hand (5, Taschen/Fallschirme), feet (6, Schuhe), teef (7, Accessoires wie Ketten), accs (8, Unterhemden/Körperaccessoires), task (9, Körperpanzer), decl (10, Aufnäher/Abzeichen), und jbib (11, Oberteile/Jacken). Props verwenden ein anderes System: p_head (Hüte), p_eyes (Brillen), p_ears (Ohrringe), und p_lwrist/p_rwrist (Uhren/Armbänder).

-- Component ID reference for scripting
local ComponentNames = {
    [0]  = 'head',   -- Face (not clothing)
    [1]  = 'berd',   -- Masks
    [2]  = 'hair',   -- Hair styles
    [3]  = 'uppr',   -- Arms / Gloves
    [4]  = 'lowr',   -- Pants / Legs
    [5]  = 'hand',   -- Bags / Parachutes
    [6]  = 'feet',   -- Shoes
    [7]  = 'teef',   -- Accessories (chains, ties)
    [8]  = 'accs',   -- Undershirts
    [9]  = 'task',   -- Body Armor
    [10] = 'decl',   -- Decals / Badges
    [11] = 'jbib',   -- Tops / Jackets
}

-- Get total drawables for a component (useful for clothing menus)
local function GetMaxDrawables(ped, componentId)
    return GetNumberOfPedDrawableVariations(ped, componentId)
end

-- Get texture count for a specific drawable
local function GetMaxTextures(ped, componentId, drawableId)
    return GetNumberOfPedTextureVariations(ped, componentId, drawableId)
end

-- Apply clothing to ped
local function SetClothing(ped, componentId, drawableId, textureId)
    SetPedComponentVariation(ped, componentId, drawableId, textureId, 0)
end

YMT-Dateien verstehen

Die YMT-Datei (Ped-Metadaten) hält ein Kleidungspaket zusammen. Sie basiert auf XML und teilt der Game-Engine mit, wie viele Drawables es pro Komponente gibt, wie viele Texturen jedes Drawable hat, welche Audioeffekte beim Bewegen der Kleidung abgespielt werden und welche Rendering-Eigenschaften gelten. Ohne eine korrekt konfigurierte YMT-Datei erkennt das Spiel deine Drawables nicht, selbst wenn die YDD- und YTD-Dateien perfekt erstellt wurden. Die YMT-Datei muss jede einzelne Drawable- und Texturkombination in deinem Paket auflisten. Fehlt ein Eintrag, wird das entsprechende Kleidungsstück unsichtbar. YMT-Dateien von Hand zu bearbeiten ist fehleranfällig. Deshalb verwenden die meisten Creator Tools wie CodeWalker oder spezielle YMT-Generatoren, die die Datei automatisch anhand der Inhalte deines Asset-Ordners erstellen.

<!-- Simplified YMT structure (XML representation) -->
<CPedVariationInfo>
  <availComp>
    <!-- Bitfield indicating which components have data -->
    <Item value="2048" />  <!-- Only jbib (component 11) -->
  </availComp>
  <compInfos>
    <Item> <!-- Component 11 (jbib / tops) -->
      <drawblDict>
        <Item>  <!-- Drawable 0 -->
          <numAlternatives value="0" />
          <numTexVariations value="3" />  <!-- 3 color variants -->
          <clothData>
            <ownsCloth value="false" />
          </clothData>
        </Item>
        <Item>  <!-- Drawable 1 -->
          <numAlternatives value="0" />
          <numTexVariations value="2" />  <!-- 2 color variants -->
          <clothData>
            <ownsCloth value="false" />
          </clothData>
        </Item>
      </drawblDict>
    </Item>
  </compInfos>
</CPedVariationInfo>

Texturvarianten und Qualität

Jedes Drawable kann mehrere Texturvarianten haben, die verschiedene Farben oder Muster desselben Kleidungsmodells darstellen. Die Basistexturdatei folgt dem Namensmuster [pack]_[component]_diff_[drawableIndex]_[textureIndex]_uni.ytd. Texturen sollten für eine optimale GPU-Kompatibilität in Zweierpotenzen erstellt werden (512x512, 1024x1024, 2048x2048). Höher aufgelöste Texturen sehen besser aus, verbrauchen aber mehr VRAM. Dieser ist besonders auf Servern begrenzt, auf denen Spieler gleichzeitig Dutzende benutzerdefinierte Kleidungspakete laden. Als praktische Richtlinie gilt: Verwende für die meisten Kleidungsstücke 1024x1024 und reserviere 2048x2048 für Stücke mit feinen Details wie gestickten Logos oder komplexen Mustern. Jede YTD-Datei kann mehrere Textur-Layer enthalten, darunter Diffuse- (Farbe), Normal- (Oberflächendetails) und Specular-Maps (Glanz). Die meisten FiveM-Kleidungspakete verwenden jedoch nur den Diffuse-Layer, um die Dateigröße überschaubar zu halten.

Ein Kleidungsauswahl-Script erstellen

Sobald deine Streaming-Ressource funktioniert, brauchst du eine Möglichkeit, mit der Spieler Kleidung durchsuchen und anziehen können. Ein Kleidungsauswahl-Script durchläuft alle verfügbaren Drawables pro Komponente und lässt Spieler sie in Echtzeit an ihrem Charakter ansehen. Die Kernlogik verwendet GetNumberOfPedDrawableVariations um zu ermitteln, wie viele Drawables es für jede Komponente gibt, und dann SetPedComponentVariation um das ausgewählte Drawable anzuwenden. Verpacke das Ganze in ein ox_lib- oder NUI-Menü, um ein ausgereiftes Nutzererlebnis zu schaffen. Schwierig ist es, Vorschauen aus der Ego-Perspektive und Kamerawinkel so zu handhaben, dass Spieler die Kleidung beim Anprobieren ohne störendes Clipping oder Zoomprobleme sehen können.

-- client/clothing_menu.lua
local function OpenClothingMenu()
    local ped = PlayerPedId()
    local components = {}

    for compId = 0, 11 do
        local maxDrawables = GetNumberOfPedDrawableVariations(ped, compId)
        if maxDrawables > 0 then
            local currentDrawable = GetPedDrawableVariation(ped, compId)
            local currentTexture = GetPedTextureVariation(ped, compId)
            local maxTextures = GetNumberOfPedTextureVariations(ped, compId, currentDrawable)

            table.insert(components, {
                id = compId,
                label = ComponentNames[compId] or ('Component ' .. compId),
                drawable = currentDrawable,
                texture = currentTexture,
                maxDrawable = maxDrawables - 1,
                maxTexture = maxTextures - 1,
            })
        end
    end

    -- Build menu options
    local options = {}
    for _, comp in ipairs(components) do
        options[#options + 1] = {
            title = comp.label,
            description = ('Drawable: %d/%d | Texture: %d/%d'):format(
                comp.drawable, comp.maxDrawable, comp.texture, comp.maxTexture),
            onSelect = function()
                OpenComponentEditor(comp.id)
            end
        }
    end

    lib.registerContext({ id = 'clothing_menu', title = 'Wardrobe', options = options })
    lib.showContext('clothing_menu')
end

local function OpenComponentEditor(componentId)
    local ped = PlayerPedId()
    local maxDraw = GetNumberOfPedDrawableVariations(ped, componentId) - 1

    -- Interactive drawable browser with live preview
    local input = lib.inputDialog('Select Clothing', {
        { type = 'slider', label = 'Style', min = 0, max = maxDraw, default = GetPedDrawableVariation(ped, componentId) },
    })

    if input then
        local drawableId = input[1]
        local maxTex = GetNumberOfPedTextureVariations(ped, componentId, drawableId) - 1
        SetPedComponentVariation(ped, componentId, drawableId, 0, 0)

        if maxTex > 0 then
            local texInput = lib.inputDialog('Select Color', {
                { type = 'slider', label = 'Variant', min = 0, max = maxTex, default = 0 },
            })
            if texInput then
                SetPedComponentVariation(ped, componentId, drawableId, texInput[1], 0)
            end
        end
    end
end

Häufige Probleme und Fehlerbehebung

Am häufigsten wird Kleidung unsichtbar oder als falsches Kleidungsstück angezeigt. Das liegt fast immer an einer fehlerhaften YMT-Datei, in der die Anzahl der Drawables oder Texturen nicht korrekt angegeben ist. Überprüfe, ob deine YMT-Datei genau die Anzahl der Drawables und Texturen auflistet, die in deinem Stream-Ordner vorhanden sind. Ein weiteres häufiges Problem ist die Ladereihenfolge der Ressource: Wenn dein Kleidungspaket vor den Basis-Assets des Spiels geladen wird, können sich die Drawable-Indizes überschneiden und Standardkleidung überschreiben. Stelle deinem Ressourcennamen zzz_ voran, damit sie zuletzt geladen wird. Unscharfe Texturen weisen meist darauf hin, dass die YTD-Datei eine zu niedrige Auflösung verwendet oder die Mipmaps nicht korrekt generiert wurden. Generiere beim Exportieren deiner YTD-Dateien in CodeWalker immer Mipmaps. Wenn Kleidung schließlich bei männlichen, aber nicht bei weiblichen Modellen angezeigt wird oder umgekehrt, überprüfe, ob du separate Ordner für mp_m_freemode_01 und mp_f_freemode_01 mit korrekt geschlechtsspezifischen Mesh-Dateien, da männliche und weibliche Ped-Modelle unterschiedliche Skelett-Rigs haben und separate Geometrie benötigen.

Optimierung der Serverleistung

Benutzerdefinierte Kleidungspakete gehören zu den größten Faktoren für die Downloadgröße des Servers und den VRAM-Verbrauch auf dem Client. Ein einziges schlecht optimiertes Paket mit 100 hochauflösenden Artikeln kann den erforderlichen Server-Download um mehrere Gigabyte vergrößern. Damit alles im Rahmen bleibt, komprimiere deine YTD-Texturen im DXT5- oder BC7-Format. So erhältst du eine gute Bildqualität bei einem Bruchteil der ursprünglichen Dateigröße. Begrenze jedes Paket auf eine angemessene Anzahl von Artikeln, normalerweise 20 bis 50 Stück, und teile größere Sammlungen auf mehrere Ressourcen auf, die unabhängig voneinander geladen werden können. Erwäge, für beliebte Pakete eine „Lite“-Version mit 512x512-Texturen für Spieler mit leistungsschwächerer Hardware anzubieten. Vermeide es auf der Skriptseite, wiederholt aufzurufen SetPedComponentVariation in einer Schleife, da jeder Aufruf eine Modellaktualisierung auslöst. Bündele Kleidungsänderungen, indem du alle Komponentenaktualisierungen sammelst und sie innerhalb eines einzelnen Frames nacheinander anwendest. So minimierst du sichtbare Sprünge und den Rendering-Aufwand.

Bereit loszulegen?

Hol dir die Scripts in unserem Shop, oder komm auf den Discord für Support, Updates und einen Blick auf das, was kommt.