Zurück zum Blog
Tutorial7 Min. Lesezeit

FiveM-Charaktererstellung: Anleitung zu Oberfläche und Skripten

Gestalte einen beeindruckenden Bildschirm zur Charaktererstellung in FiveM. Mit Gesichtsreglern, Kleidung, Hintergrundszenen und den besten kostenlosen und kostenpflichtigen Tools.

Agency Scripts

Gründer und leitender Entwickler bei Agency Scripts

Warum die Charaktererstellung im Rollenspiel wichtig ist

Die Charaktererstellung ist der erste interaktive Moment, den ein Spieler auf deinem FiveM-Rollenspielserver erlebt. Sie gibt den Ton für alles Weitere an. Ein ausgefeilter, immersiver Charaktereditor vermittelt neuen Spielern, dass dein Server professionell gestaltet ist und es sich lohnt, Zeit in ihn zu investieren. Ein einfacher oder fehlerhafter Editor treibt sie direkt zurück zur Serverliste, wo sie nach Alternativen suchen. Über den ersten Eindruck hinaus legt der Charaktereditor die visuelle Identität fest, die jeder Spieler während seines gesamten Rollenspielerlebnisses verkörpert. Er bestimmt die Mischung der Herkunftsmerkmale, Gesichtszüge, Frisuren, Kleidung und biografische Angaben wie Name und Geburtsdatum. Damit das gelingt, brauchst du ein System, das mit dem nativen Erscheinungsbildsystem von GTA V kommuniziert, die Optionen über eine intuitive NUI-Oberfläche bereitstellt, Auswahlen in einer Datenbank speichert und bei jedem Spawn zuverlässig wieder lädt.

Das Ped-Erscheinungsbildsystem von GTA V verstehen

GTA V verwendet ein herkunftsbasiertes Erscheinungsbildsystem, bei dem das Gesicht eines Charakters aus zwei Elternmodellen zusammengesetzt wird. Es gibt 46 mögliche Mütter und Väter mit jeweils eigenen Gesichtsstrukturen. Die SetPedHeadBlendData native Funktion steuert diese Mischung. Sie akzeptiert Shape- und Skin-Mix-Werte zwischen 0.0 und 1.0, die bestimmen, wie stark der Charakter jedem Elternteil ähnelt. Neben der Herkunft bietet das Spiel über SetPedHeadOverlay 20 Overlay-Kategorien, darunter Merkmale wie Hautunreinheiten, Gesichtsbehaarung, Augenbrauen, Alterung, Make-up und Hautschäden. Jedes Overlay hat einen eigenen Deckkraftwert und kann separat eingefärbt werden mit SetPedHeadOverlayColor. Haare werden separat über SetPedComponentVariation für das Modell und SetPedHairColor für Farbe und Highlights angepasst. Die Augenfarbe wird über SetPedEyeColor mit Werten von 0 bis 31 festgelegt. Diese Natives zu verstehen, ist entscheidend, denn deine NUI-Oberfläche muss benutzerfreundliche Schieberegler und Auswahlfelder diesen spezifischen Funktionsaufrufen zuordnen.

-- client/appearance.lua
function ApplyAppearance(ped, data)
    -- Heritage blend (mother, father, shape mix, skin mix)
    SetPedHeadBlendData(ped,
        data.mother, data.father, 0,
        data.mother, data.father, 0,
        data.shapeMix, data.skinMix, 0.0,
        false
    )

    -- Face features (-1.0 to 1.0 for each of 20 features)
    for i = 0, 19 do
        SetPedFaceFeature(ped, i, data.features[i] or 0.0)
    end

    -- Overlays (blemishes, beard, eyebrows, aging, makeup, etc.)
    for i = 0, 12 do
        local overlay = data.overlays[i] or {style = 0, opacity = 0.0}
        SetPedHeadOverlay(ped, i, overlay.style, overlay.opacity)
        if overlay.color then
            SetPedHeadOverlayColor(ped, i, overlay.colorType or 1,
                overlay.color, overlay.secondColor or overlay.color)
        end
    end

    -- Hair
    SetPedComponentVariation(ped, 2, data.hair or 0, 0, 2)
    SetPedHairColor(ped, data.hairColor or 0, data.hairHighlight or 0)

    -- Eye color
    SetPedEyeColor(ped, data.eyeColor or 0)
end

Die NUI-Oberfläche erstellen

Die NUI (Natural User Interface) ist die HTML-, CSS- und JavaScript-Einblendung, mit der Spieler bei der Erstellung ihres Charakters interagieren. Ein gut gestalteter Charaktereditor unterteilt den Prozess in logische Schritte: zuerst biografische Angaben, dann die Auswahl der Abstammung, Gesichtszüge, Overlays wie Bart und Make-up, Haarstyling und schließlich Kleidung. Bei jedem Schritt sollten die Änderungen am Charaktermodell in Echtzeit angezeigt werden, damit Spieler genau sehen, wie ihre Auswahl aussieht. Verwende ein Layout mit Tabs oder Assistenten, damit Spieler nicht von Dutzenden Optionen auf einmal überfordert werden. Schieberegler eignen sich gut für kontinuierliche Werte wie die Abstimmung der Gesichtsform und Gesichtszüge, während Raster mit Vorschaubildern für einzelne Optionen wie Frisuren und Kleidungsstücke besser geeignet sind. Übertrage jede Änderung mit fetch oder dem NUI-Nachrichtensystem an das Client-Skript, damit sich der Ped sofort aktualisiert.

<!-- nui/index.html (simplified structure) -->
<div id="creator" class="creator-wrapper">
  <div class="steps-nav">
    <button data-step="bio" class="active">Identity</button>
    <button data-step="heritage">Heritage</button>
    <button data-step="features">Features</button>
    <button data-step="overlays">Appearance</button>
    <button data-step="hair">Hair</button>
    <button data-step="clothing">Clothing</button>
  </div>

  <div class="step-content" id="step-heritage">
    <label>Mother</label>
    <input type="range" id="mother" min="0" max="45" value="0">
    <label>Father</label>
    <input type="range" id="father" min="0" max="45" value="0">
    <label>Resemblance (Shape Mix)</label>
    <input type="range" id="shapeMix" min="0" max="100" value="50">
    <label>Skin Tone (Skin Mix)</label>
    <input type="range" id="skinMix" min="0" max="100" value="50">
  </div>
</div>

<script>
document.querySelectorAll('input[type="range"]').forEach(slider => {
  slider.addEventListener('input', () => {
    fetch('https://myresource/updateAppearance', {
      method: 'POST',
      body: JSON.stringify({
        type: slider.id,
        value: parseFloat(slider.value)
      })
    });
  });
});
</script>

Kamerasystem für die Charaktervorschau

Ein eigenes Kamerasystem ist entscheidend für ein ausgefeiltes Charaktererstellungserlebnis. Spieler brauchen Nahaufnahmen der Gesichtszüge, wenn sie Abstammungsmischungen und Overlays anpassen, Halbtotalen für Haare und Oberkörperkleidung sowie Ganzkörperansichten für Hosen und Schuhe. Implementiere einen Kameracontroller, der sanft zwischen vordefinierten Positionen wechselt, je nachdem, welcher Schritt der Erstellung gerade aktiv ist. Verwende CreateCam mit dem Typ DEFAULT_SCRIPTED_CAMERA und RenderScriptCams um die Kontrolle von der Spielkamera zu übernehmen. Bei der Drehung können Spieler die Maus ziehen, um die Kamera um ihren Charakter kreisen zu lassen. Passe dazu die Kameraausrichtung an und richte sie weiterhin auf den Ped. Eine dezente Idle-Animation am Ped, etwa das Szenario WORLD_HUMAN_STAND_IMPATIENT sorgt dafür, dass der Charakter während der Erstellung natürlich wirkt und nicht steif in einer T-Pose dasteht.

-- client/camera.lua
local creatorCam = nil
local camAngle = 0.0

local CamPositions = {
    bio      = {offset = vector3(0.0, 0.9, 0.65), fov = 35.0},
    heritage = {offset = vector3(0.0, 0.7, 0.65), fov = 30.0},
    features = {offset = vector3(0.0, 0.5, 0.68), fov = 22.0},
    overlays = {offset = vector3(0.0, 0.5, 0.68), fov = 22.0},
    hair     = {offset = vector3(0.0, 0.6, 0.72), fov = 25.0},
    clothing = {offset = vector3(0.0, 2.2, 0.30), fov = 45.0},
}

function SetupCreatorCam(ped, step)
    local pos = CamPositions[step] or CamPositions.bio
    local pedCoords = GetEntityCoords(ped)
    local target = pedCoords + vector3(0.0, 0.0, pos.offset.z)

    if not creatorCam then
        creatorCam = CreateCam('DEFAULT_SCRIPTED_CAMERA', true)
        RenderScriptCams(true, true, 500, true, false)
    end

    local rad = math.rad(camAngle)
    local camPos = pedCoords + vector3(
        math.sin(rad) * pos.offset.y,
        math.cos(rad) * pos.offset.y,
        pos.offset.z
    )

    SetCamCoord(creatorCam, camPos.x, camPos.y, camPos.z)
    PointCamAtCoord(creatorCam, target.x, target.y, target.z)
    SetCamFov(creatorCam, pos.fov)
    SetCamActive(creatorCam, true)
end

Charakterdaten speichern und laden

Alle Daten zum Aussehen des Charakters müssen in einer Datenbank gespeichert werden, damit sie Serverneustarts überstehen und bei jedem Spawn des Spielers geladen werden können. Lege deine Datenbanktabelle so an, dass sie das vollständige Aussehen als JSON-Blob sowie biografische Angaben wie Vorname, Nachname, Geburtsdatum, Geschlecht und Nationalität speichert. Wenn der Spieler die Erstellung abgeschlossen und seinen Charakter bestätigt hat, sendet der Client das vollständige Datenobjekt an den Server, der die Wertebereiche überprüft und die Daten in die Datenbank einfügt. Bei späteren Logins ruft der Server die Charakterdaten während des Spawn-Ablaufs ab und sendet sie an den Client zurück, der dieselbe ApplyAppearance Funktion aufruft, die auch bei der Erstellung verwendet wird. Speichere bei Multicharakter-Servern eine Charakter-Slot-ID, damit jeder Spieler mehrere Charaktere mit unabhängigem Aussehen haben kann.

-- server/database.lua
-- Using oxmysql for database operations
function SaveCharacter(playerId, charData)
    local identifier = GetPlayerIdentifier(playerId, 0)
    local appearance = json.encode(charData.appearance)

    MySQL.insert([[
        INSERT INTO characters
            (identifier, slot, firstname, lastname,
             dateofbirth, gender, nationality, appearance)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    ]], {
        identifier,
        charData.slot or 1,
        charData.firstname,
        charData.lastname,
        charData.dob,
        charData.gender,
        charData.nationality,
        appearance
    })
end

function LoadCharacter(playerId, slot)
    local identifier = GetPlayerIdentifier(playerId, 0)
    local result = MySQL.single.await([[
        SELECT * FROM characters
        WHERE identifier = ? AND slot = ?
    ]], {identifier, slot})

    if result then
        result.appearance = json.decode(result.appearance)
    end
    return result
end

-- Spawn handler
RegisterNetEvent('character:loaded', function(slot)
    local src = source
    local char = LoadCharacter(src, slot)
    if char then
        TriggerClientEvent('character:applyAppearance', src, char.appearance)
    end
end)

Kleidungsintegration und Komponentenvarianten

Kleidung in GTA V wird über Komponentenvarianten und Prop-Varianten verwaltet. Komponenten umfassen Körperteile und Bereiche wie Oberkörper, Beine, Füße, Accessoires und Unterhemden, während Props aufsetzbare oder tragbare Gegenstände wie Hüte, Brillen, Ohrringe und Uhren abdecken. Der SetPedComponentVariation Native benötigt eine Komponenten-ID, Drawable-ID, Textur-ID und Paletten-ID. Die Herausforderung besteht darin, dass sich die verfügbaren Drawables je nach männlichem oder weiblichem Ped-Modell unterscheiden und manche Kombinationen aus Drawables und Texturen ungültig sind. Deine NUI muss die maximale Anzahl an Drawables für jede Komponente mit GetNumberOfPedDrawableVariations und die maximale Anzahl an Texturen für jedes Drawable mit GetNumberOfPedTextureVariationsermitteln. Gestalte deine Kleiderauswahl so, dass die Optionen je nach ausgewähltem Geschlecht dynamisch befüllt werden und Spieler nur gültige Kombinationen sehen. Speichere die Kleidungsdaten zusammen mit den Daten zum Aussehen und wende sie während des Spawn-Ablaufs mit denselben Natives für Komponentenvarianten an.

Validierung und Maßnahmen gegen Missbrauch

Vertraue niemals Daten vom Client, ohne sie zu validieren. Spieler mit modifizierten Clients können Werte für das Aussehen außerhalb der normalen Bereiche senden, wodurch andere Clients möglicherweise abstürzen oder visuelle Fehler ausgenutzt werden. Validiere jedes Feld serverseitig, bevor du es in der Datenbank speicherst. Abstammungsindizes müssen zwischen 0 und 45 liegen, Mischwerte zwischen 0.0 und 1.0, Werte für Gesichtszüge zwischen -1.0 und 1.0 und Overlay-Indizes innerhalb des gültigen Bereichs für den jeweiligen Overlay-Typ. Weise Werte außerhalb des zulässigen Bereichs zurück oder begrenze sie auf den gültigen Bereich. Begrenze außerdem die Häufigkeit von Ereignissen zur Aktualisierung des Aussehens während der Erstellung, damit böswillige Clients den Server nicht mit schnellen Änderungen überfluten können. Eine Abklingzeit von 100 Millisekunden zwischen Aktualisierungen ist für reguläre Spieler nicht wahrnehmbar, verhindert aber automatisierten Spam. Sichere den Charaktererstellungsablauf schließlich mit einer ordnungsgemäßen Sitzungsverwaltung ab, damit Spieler keine Erstellungsereignisse außerhalb des vorgesehenen Ablaufs auslösen können.

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.