Ekran tworzenia postaci FiveM: poradnik dotyczący UI i skryptowania
Zaprojektuj zachwycający kreator postaci dla FiveM. Ustawienia twarzy, ubrania, sceny w tle oraz najlepsze darmowe i płatne kreatory postaci.
Agency Scripts
Założyciel i główny deweloper w Agency Scripts
Dlaczego tworzenie postaci ma znaczenie w Roleplay
Tworzenie postaci to pierwszy interaktywny moment, jakiego gracz doświadcza na twoim serwerze roleplay FiveM. Nadaje ton wszystkiemu, co następuje później. Dopracowany, immersyjny kreator postaci pokazuje nowym graczom, że twój serwer jest profesjonalnie zbudowany i wart ich czasu. Podstawowy lub zabugowany kreator od razu odsyła ich do przeglądarki serwerów w poszukiwaniu alternatyw. Poza pierwszym wrażeniem kreator postaci definiuje tożsamość wizualną, którą każdy gracz nosi przez całe swoje doświadczenie roleplay. Określa cechy dziedziczone, rysy twarzy, fryzury, ubrania oraz dane biograficzne, takie jak imię i data urodzenia. Właściwe wykonanie tego elementu oznacza zbudowanie systemu, który komunikuje się z natywnym systemem wyglądu GTA V, prezentuje opcje za pośrednictwem intuicyjnego interfejsu NUI, zapisuje wybory w bazie danych i niezawodnie wczytuje je za każdym razem, gdy gracz się odradza.
Zrozumienie systemu wyglądu pedów w GTA V
GTA V korzysta z systemu wyglądu opartego na dziedziczeniu, w którym twarz postaci powstaje z połączenia cech modeli dwojga rodziców. Dostępnych jest 46 potencjalnych matek i ojców, każdy o odmiennej strukturze twarzy. Ten SetPedHeadBlendData native kontroluje to mieszanie, przyjmując wartości kształtu i koloru skóry od 0.0 do 1.0, które określają, jak bardzo postać przypomina każdego z rodziców. Oprócz dziedziczenia gra oferuje 20 kategorii nakładek poprzez SetPedHeadOverlay obejmując takie cechy jak niedoskonałości, zarost, brwi, starzenie się, makijaż i uszkodzenia skóry. Każda nakładka (overlay) ma własną wartość przezroczystości i może być kolorowana niezależnie za pomocą SetPedHeadOverlayColor. Włosy są obsługiwane osobno poprzez SetPedComponentVariation dla modelu oraz SetPedHairColor dla koloru i refleksów. Kolor oczu wykorzystuje SetPedEyeColor z wartościami od 0 do 31. Zrozumienie tych natives jest kluczowe, ponieważ twój interfejs NUI musi mapować przyjazne dla użytkownika suwaki i selektory na te konkretne wywołania funkcji.
-- 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
Tworzenie interfejsu NUI
NUI (Natural User Interface) to nakładka HTML, CSS i JavaScript, z którą gracze wchodzą w interakcję podczas tworzenia postaci. Dobrze zaprojektowany kreator postaci dzieli ten proces na logiczne kroki: najpierw dane biograficzne, potem wybór pochodzenia, rysy twarzy, detale takie jak zarost i makijaż, fryzura, a na końcu ubrania. Każdy krok powinien wyświetlać podgląd w czasie rzeczywistym na modelu postaci, aby gracze widzieli dokładnie, jak wyglądają ich wybory. Zastosuj układ z zakładkami lub kreator krok po kroku (wizard), aby gracze nie czuli się przytłoczeni dziesiątkami opcji naraz. Suwaki sprawdzają się dobrze w przypadku wartości ciągłych, takich jak proporcje twarzy i rysy, natomiast siatki wyboru z miniaturami podglądu są lepsze dla opcji dyskretnych, takich jak fryzury czy elementy garderoby. Przesyłaj każdą zmianę do skryptu klienckiego przez fetch lub system wiadomości NUI, dzięki czemu ped aktualizuje się natychmiastowo.
<!-- 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>
System kamery do podglądu postaci
Dedykowany system kamer jest kluczowy dla dopracowanego kreatora postaci. Gracze muszą widzieć zbliżenia rysów twarzy podczas dopasowywania cech dziedzicznych i nakładek, średnie plany dla fryzur i ubrań górnej części ciała oraz widok całej sylwetki dla spodni i butów. Zaimplementuj kontroler kamery, który płynnie interpoluje między zdefiniowanymi pozycjami w zależności od aktywnego etapu tworzenia. Użyj CreateCam z DEFAULT_SCRIPTED_CAMERA typ i RenderScriptCams aby przejąć kontrolę nad kamerą gry. W przypadku obracania pozwól graczom przeciągać myszą, aby obracać widok wokół postaci poprzez dostosowywanie kąta kamery przy jednoczesnym utrzymaniu jej skierowanej na peda. Subtelna animacja bezczynności peda, taka jak WORLD_HUMAN_STAND_IMPATIENT scenariusz, sprawia, że postać wygląda naturalnie podczas procesu tworzenia, zamiast stać w sztywnym T-pose.
-- 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
Zapisywanie i wczytywanie danych postaci
Wszystkie dane dotyczące wyglądu postaci muszą być trwale zapisane w bazie danych, aby przetrwały restarty serwera i mogły być ładowane za każdym razem, gdy gracz się spawnuje. Zaprojektuj tabelę w bazie danych tak, aby przechowywała kompletny wygląd jako obiekt JSON obok pól biograficznych, takich jak imię, nazwisko, data urodzenia, płeć i narodowość. Kiedy gracz zakończy tworzenie i zatwierdzi swoją postać, klient wysyła pełny obiekt danych do serwera, który sprawdza zakresy wprowadzonych wartości i wstawia go do bazy danych. Przy kolejnych logowaniach serwer pobiera dane postaci podczas procesu spawnowania i odsyła je do klienta, który wywołuje to samo ApplyAppearance funkcja używana podczas tworzenia. W przypadku serwerów multicharacter zapisuj identyfikator slotu postaci, dzięki czemu każdy gracz może mieć wiele postaci o niezależnym wyglądzie.
-- 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)
Integracja ubrań i warianty komponentów
Ubrania w GTA V są zarządzane za pomocą wariantów komponentów i wariantów rekwizytów. Komponenty obejmują części ciała, takie jak tułów, nogi, stopy, akcesoria i podkoszulki, podczas gdy rekwizyty obsługują dołączane elementy, takie jak czapki, okulary, kolczyki i zegarki. Ten SetPedComponentVariation native przyjmuje ID komponentu, ID drawable, ID tekstury i ID palety. Wyzwaniem jest to, że dostępne modele drawable różnią się między męskimi i żeńskimi pedami, a niektóre kombinacje drawable i tekstur są nieprawidłowe. Twoje NUI musi odpytywać o maksymalną liczbę drawable dla każdego komponentu za pomocą GetNumberOfPedDrawableVariations oraz maksymalną liczbę tekstur dla każdego drawable przy użyciu GetNumberOfPedTextureVariations. Zbuduj selektor ubrań tak, aby dynamicznie uzupełniał opcje na podstawie wybranej płci, dzięki czemu gracze widzą tylko poprawne kombinacje. Przechowuj dane ubrań razem z danymi wyglądu i aplikuj je podczas procedury spawnu przy użyciu tych samych natywnych funkcji wariacji komponentów.
Walidacja i środki przeciw nadużyciom
Nigdy nie ufaj danym pochodzącym od klienta bez walidacji. Gracze ze zmodyfikowanymi klientami mogą przesyłać wartości wyglądu spoza standardowych zakresów, co może powodować crashowanie innych klientów lub wykorzystywanie błędów wizualnych. Waliduj każde pole po stronie serwera przed zapisaniem do bazy danych. Indeksy dziedziczenia muszą mieścić się w przedziale od 0 do 45, wartości miksowania od 0.0 do 1.0, wartości rysów twarzy od -1.0 do 1.0, a indeksy overlay w prawidłowym zakresie dla każdego typu nakładki. Odrzucaj lub ograniczaj (clamp) wszelkie wartości spoza zakresu. Dodatkowo wdróż rate limiting dla eventów aktualizacji wyglądu podczas tworzenia postaci, aby uniemożliwić złośliwym klientom zalewanie serwera lawinowymi zmianami wyglądu. Cooldown wynoszący 100 milisekund między aktualizacjami jest niezauważalny dla uczciwych graczy, ale blokuje automatyczny spam. Na koniec zabezpiecz proces tworzenia postaci za pomocą właściwego zarządzania sesją, aby gracze nie mogli wywoływać eventów tworzenia poza zamierzonym schematem.