إضافات الملابس المخصصة لـ FiveM: بث التنزيلات الخاصة بك
بث ملابسك المخصصة في FiveM. إعداد الإضافات، التعامل مع الفتحات، إصلاح التعارضات وتعلم سير العمل وراء بناء إصدارات حصرية للخادم.
Agency Scripts
المؤسس والمطور الرئيسي في Agency Scripts
فهم نظام الملابس في GTA V
تستخدم GTA V نظام ملابس قائم على المكونات حيث كل قطعة ملابس هي "drawable" ضمن فتحة مكون محددة. هناك 12 فتحة مكون على شخصية، تتراوح من الرأس (المكون 0) إلى الأحذية (المكون 6) وصولاً إلى الحقائب والإكسسوارات. يمكن لكل فتحة مكون أن تحتوي على عدة drawables، ولكل drawable يمكن أن يكون له عدة تنويعات نسيجية. على سبيل المثال، المكون 11 (القمصان) قد يحتوي على drawable 15 (سترة جلدية) مع تنويعات نسيج 0 حتى 3 تمثل الألوان الأسود والبني والأحمر والأبيض. فهم هذا التسلسل الهرمي للمكونات والdrawables والنسيج ضروري قبل أن تتمكن من إنشاء ملابس مخصصة لأن كل قطعة تضيفها يجب أن تتناسب ضمن هذا الهيكل الموجود. يضيف نموذج شخصية اللاعبين المتعددين (MP) طبقة أخرى مع تعيين drawable خاص به يختلف عن شخصيات اللاعب الواحد، وتستخدم خوادم FiveM حصرياً نماذج MP freemode.
هيكل الموارد والبث
الملابس المخصصة في FiveM تعمل من خلال نظام البث. تقوم بإنشاء مورد يخبر اللعبة بتحميل ملفات drawable وtexture إضافية إلى جانب أصول اللعبة الأساسية. يتبع هيكل المورد قواعد تسمية صارمة يستخدمها محرك اللعبة لتحديد نموذج الشخصية، والمكون، وفهرس drawable الذي ينتمي إليه كل ملف. الخطأ في هيكل المجلد هو السبب الأكثر شيوعًا لعدم ظهور الملابس داخل اللعبة. يحتاج المورد الخاص بك إلى fxmanifest.lua التي تعلن عن ملفات البث، وتذهب بيانات الملابس الفعلية إلى stream الدليل مع التسلسل الهرمي الصحيح للمجلدات الفرعية.
-- 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
يتبع مجلد البث تسلسلًا هرميًا دقيقًا. لملابس الذكور في وضع MP freemode، توضع الملفات في stream/mp_m_freemode_01_mp_m_[dlcname]/. بالنسبة للإناث، استبدل mp_m مع mp_f. داخل هذا المجلد، تضع ملفات YDD (قاموس الرسومات)، YTD (قاموس القوام)، و YMT (بيانات التعريف). تسمية الملفات ترمز إلى المكون ورقم الرسم الذي يمثله كل ملف. ملف اسمه mp_m_freemode_01_mp_m_mypack_jbib_000_u.ydd هو drawable 0 للمكون 11 (jbib = السترة/القمصان) على شخصية freemode الذكر من حزمة DLC "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
معرفات المكونات واتفاقيات التسمية
كل مكون ملابس له اختصار محدد يستخدم في تسمية الملفات. حفظ هذه الاختصارات أمر حاسم لأن خطأ واحد في الكتابة يعني أن اللعبة لا يمكنها العثور على الأصل الخاص بك. خريطة المكونات هي: الرأس (المكون 0، بدون ملابس)، berd (1، أقنعة)، الشعر (2), uppr (3، أذرع/قفازات)، lowr (4، بنطلونات/أرجل)، اليد (5، حقائب/مظلات)، أقدام (6، أحذية)، teef (7، إكسسوارات مثل السلاسل)، accs (8، قمصان داخلية/إكسسوارات الجسم)، مهمة (9، دروع الجسم)، decl (10، ملصقات/شارات)، و jbib (11، قمصان/سترات). تستخدم الدعائم نظامًا مختلفًا: p_head (القبعات)، p_eyes (النظارات)، p_ears (الأقراط)، و p_lwrist/p_rwrist (الساعات/الأساور).
-- 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
ملف YMT (بيانات تعريف المشاة) هو الرابط الذي يجمع حزمة الملابس معًا. إنه ملف قائم على XML يخبر محرك اللعبة بعدد العناصر القابلة للعرض في كل مكون، وعدد القوام التي يمتلكها كل عنصر، وأي صوت يتم تشغيله عند تحرك الملابس، وخصائص العرض المختلفة. بدون YMT مُعد بشكل صحيح، لن يتعرف اللعبة على عناصر العرض حتى لو كانت ملفات YDD و YTD مصممة بشكل مثالي. يجب أن يسرد YMT كل تركيبة من العناصر والقوام في حزمة الملابس الخاصة بك. غياب إدخال واحد يعني أن العنصر سيكون غير مرئي. تحرير ملفات YMT يدويًا معرض للأخطاء، ولهذا السبب يستخدم معظم المبدعين أدوات مثل CodeWalker أو مولدات YMT المخصصة التي تبني الملف تلقائيًا من محتويات مجلد الأصول الخاص بك.
<!-- 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>
تباينات وجودة النسيج
يمكن أن يحتوي كل رسم قابل للارتداء على عدة تباينات نسيجية، والتي تمثل ألوانًا أو أنماطًا مختلفة لنموذج الملابس نفسه. يستخدم ملف النسيج الأساسي نمط التسمية [pack]_[component]_diff_[drawableIndex]_[textureIndex]_uni.ytd. يجب إنشاء الخامات بقوى اثنين (512x512، 1024x1024، 2048x2048) لتحقيق أفضل توافق مع وحدة معالجة الرسومات. الخامات ذات الدقة الأعلى تبدو أفضل لكنها تستهلك المزيد من VRAM، وهو مورد محدود خاصة على الخوادم حيث يحمل اللاعبون عشرات حزم الملابس المخصصة في نفس الوقت. قاعدة عملية هي استخدام 1024x1024 لمعظم الملابس و2048x2048 للعناصر ذات التفاصيل الدقيقة مثل الشعارات المطرزة أو الأنماط المعقدة. يمكن لكل ملف YTD أن يحتوي على طبقات خام متعددة تشمل diffuse (اللون)، normal (تفاصيل السطح)، وspecular (اللمعان)، رغم أن معظم حزم الملابس في FiveM تستخدم فقط طبقة diffuse للحفاظ على حجم الملفات قابل للإدارة.
بناء سكربت قائمة الملابس
بمجرد أن يعمل مورد البث الخاص بك، تحتاج إلى طريقة للاعبين لتصفح الملابس وتطبيقها. سكربت قائمة الملابس يتكرر عبر جميع العناصر المتاحة لكل مكون ويتيح للاعبين معاينتها على شخصياتهم في الوقت الحقيقي. المنطق الأساسي يستخدم GetNumberOfPedDrawableVariations لتحديد عدد العناصر القابلة للرسم لكل مكون، ثم SetPedComponentVariation لتطبيق المختار. غلف هذا في قائمة ox_lib أو NUI لتجربة مستخدم مصقولة. الجزء الصعب هو التعامل مع المعاينات من منظور الشخص الأول وزوايا الكاميرا حتى يتمكن اللاعبون من رؤية ما يجربونه بدون تقطيع أو مشاكل تكبير.
-- 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
المشاكل الشائعة واستكشاف الأخطاء وإصلاحها
المشكلة الأكثر شيوعًا هي ظهور الملابس كغير مرئية أو كعنصر خاطئ. يعود ذلك غالبًا إلى ملف YMT غير صحيح لا يعلن بشكل صحيح عن عدد العناصر القابلة للارتداء أو عدد القوام. تحقق من أن YMT الخاص بك يسرد العدد الدقيق للعناصر والقوام الموجودة في مجلد البث الخاص بك. مشكلة شائعة أخرى هي ترتيب تحميل الموارد: إذا تم تحميل حزمة الملابس قبل أصول اللعبة الأساسية، يمكن أن تتصادم مؤشرات العناصر القابلة للارتداء وتستبدل ملابس اللعبة الأصلية. أضف بادئة لاسم المورد الخاص بك مع zzz_ للتأكد من تحميله أخيرًا. عادةً ما يشير ضبابية النسيج إلى أن YTD يستخدم دقة منخفضة جدًا أو أن mipmaps لم تُولد بشكل صحيح. دائمًا قم بإنشاء mipmaps عند تصدير ملفات YTD في CodeWalker. أخيرًا، إذا ظهرت الملابس على نماذج الذكور ولكن ليس الإناث أو العكس، تحقق جيدًا من أن لديك مجلدات منفصلة لـ mp_m_freemode_01 و mp_f_freemode_01 مع ملفات الشبكة المصنفة حسب الجنس بشكل صحيح، لأن نماذج الشخصيات الذكرية والأنثوية لها هياكل عظمية مختلفة وتتطلب هندسة منفصلة.
التحسين لأداء الخادم
حزم الملابس المخصصة هي من أكبر المساهمين في حجم تحميل الخادم واستخدام VRAM للعميل. يمكن لحزمة واحدة غير محسنة تحتوي على 100 عنصر عالي الدقة أن تضيف جيجابايت إلى متطلبات تحميل الخادم. للحفاظ على الأمور قابلة للإدارة، قم بضغط قوام YTD باستخدام تنسيق DXT5 أو BC7، الذي يوفر جودة بصرية جيدة بجزء بسيط من حجم الملف الخام. حدد كل حزمة بعدد معقول من العناصر، عادة من 20 إلى 50 قطعة، وقم بتقسيم المجموعات الأكبر عبر موارد متعددة يمكن تحميلها بشكل مستقل. فكر في تقديم نسخة "خفيفة" من الحزم الشعبية بقوام 512x512 للاعبين على أجهزة منخفضة الأداء. على جانب السكربت، تجنب الاستدعاء المتكرر SetPedComponentVariation في حلقة لأن كل استدعاء يؤدي إلى تحديث نموذج. قم بتجميع تغييرات الملابس عن طريق جمع جميع تحديثات المكونات وتطبيقها بالتسلسل ضمن إطار واحد لتقليل الوميض البصري والعبء على العرض.