ब्लॉग पर वापस
Tutorial9 मिनट पढ़ें

FiveM HUD विकास: एक साफ, तेज़ प्लेयर HUD डिज़ाइन करें

HTML और JS के साथ एक प्रदर्शनक्षम FiveM HUD बनाएं। स्वास्थ्य, स्टैमिना, आवाज़, गति और मिनीमैप ओवरले के साथ सर्वश्रेष्ठ HUD स्क्रिप्ट जो अध्ययन या खरीदने के लिए।

Agency Scripts

Agency Scripts के संस्थापक और प्रमुख डेवलपर

क्यों एक कस्टम HUD बनाएं

डिफ़ॉल्ट GTA V HUD एक एकल खिलाड़ी एक्शन गेम के लिए डिज़ाइन किया गया था, न कि उन जटिल रोलप्ले परिदृश्यों के लिए जो FiveM सर्वर मांगते हैं। एक कस्टम HUD आपको भूख, प्यास, तनाव, और नौकरी की स्थिति जैसी रोलप्ले-विशिष्ट जानकारी दिखाने देता है जो वैनिला GTA में मौजूद नहीं हैं। कार्यक्षमता से परे, एक कस्टम HUD आपके सर्वर की दृश्य पहचान को परिभाषित करता है और खिलाड़ी के स्पॉन होते ही टोन सेट करता है। खिलाड़ी तुरंत उस गुणवत्ता अंतर को नोटिस करते हैं जो डिफ़ॉल्ट UI तत्वों वाले सर्वर और एक पॉलिश्ड, उद्देश्य-निर्मित HUD वाले सर्वर के बीच होता है जो सर्वर की ब्रांडिंग और थीम से मेल खाता है। अपना HUD स्क्रैच से बनाना भी मतलब है कि आप प्रदर्शन के हर पहलू को नियंत्रित करते हैं, यह सुनिश्चित करते हुए कि ओवरले न्यूनतम संसाधन लागत पर चलता है जबकि आपके खिलाड़ियों को आवश्यक जानकारी प्रदान करता है।

NUI संसाधन संरचना

FiveM NUI (New User Interface) का उपयोग करता है जो गेम क्लाइंट के अंदर HTML, CSS, और JavaScript को रेंडर करता है। आपका HUD रिसोर्स सही ढंग से काम करने के लिए एक विशिष्ट फ़ोल्डर संरचना की आवश्यकता होती है। fxmanifest.lua फ़ाइल संसाधन मेटाडेटा घोषित करती है, client.lua स्क्रिप्ट गेम डेटा को NUI लेयर पर भेजती है, और html/ फोल्डर में आपकी वेब-आधारित इंटरफ़ेस होती है। शुरू करने के लिए यहाँ एक न्यूनतम रिसोर्स मैनिफेस्ट है:

fx_version 'cerulean'
game 'gta5'

description 'Custom HUD'
author 'YourName'
version '1.0.0'

ui_page 'html/index.html'

client_script 'client.lua'

files {
    'html/index.html',
    'html/style.css',
    'html/script.js',
    'html/fonts/*.woff2'
}

यह ui_page directive tells FiveM which HTML file to render as the NUI overlay, and the files तालिका में ब्राउज़र को आवश्यक हर एसेट की सूची होती है। यदि आप इस सूची में CSS फाइल या फॉन्ट शामिल करना भूल जाते हैं, तो ब्राउज़र बिना किसी त्रुटि संदेश के इसे लोड करने में विफल रहता है, जो NUI विकास में नए डेवलपर्स के लिए भ्रम का सामान्य स्रोत है। अपनी रिसोर्स संरचना को साफ रखें और जिम्मेदारियों को अलग करें: HTML लेआउट के लिए, CSS स्टाइलिंग के लिए, और JavaScript लॉजिक और एनिमेशन के लिए।

गेम डेटा UI को भेजना

क्लाइंट-साइड Lua स्क्रिप्ट गेम स्थिति पढ़ने और इसे नियमित अंतराल पर NUI लेयर को भेजने के लिए जिम्मेदार है। आपको स्वास्थ्य, कवच, और किसी भी फ्रेमवर्क-विशिष्ट स्थिति मान जैसे भूख और प्यास एकत्र करने की आवश्यकता है। मुख्य फ़ंक्शन है SendNUIMessage()", जो NUI फ्रेम में चल रहे जावास्क्रिप्ट को JSON पेलोड भेजता है। अपनी अपडेट आवृत्ति के बारे में रणनीतिक बनें क्योंकि हर फ्रेम डेटा भेजना CPU चक्रों की बर्बादी है जबकि बहुत धीमी अपडेटिंग HUD को लैगी बनाती है। स्थिति बार के लिए 200-500 मिलीसेकंड की टिक दर सही संतुलन बनाती है:

CreateThread(function()
    while true do
        local ped = PlayerPedId()
        local health = GetEntityHealth(ped) - 100  -- GTA health starts at 100
        local maxHealth = GetEntityMaxHealth(ped) - 100
        local armor = GetPedArmour(ped)

        -- Framework-specific data (QBCore example)
        local playerData = QBCore.Functions.GetPlayerData()
        local hunger = playerData.metadata['hunger'] or 100
        local thirst = playerData.metadata['thirst'] or 100
        local stress = playerData.metadata['stress'] or 0

        SendNUIMessage({
            action = 'updateStatus',
            health = math.floor((health / maxHealth) * 100),
            armor = armor,
            hunger = math.floor(hunger),
            thirst = math.floor(thirst),
            stress = math.floor(stress)
        })

        Wait(300)
    end
end)

स्पीडोमीटर के लिए, आपको एक अलग थ्रेड की आवश्यकता होती है जो तेज़ टिक दर पर चलता है क्योंकि गति तेजी से बदलती है और खिलाड़ी ड्राइविंग के दौरान वास्तविक समय प्रतिक्रिया की उम्मीद करते हैं। वाहन डेटा के लिए 50-100 मिलीसेकंड अंतराल अच्छा काम करता है। संसाधन बचाने के लिए केवल तब स्पीडोमीटर थ्रेड चलाएं जब खिलाड़ी वास्तव में वाहन में हो, और जब वे बाहर निकलें तो इसे अक्षम करें:

CreateThread(function()
    while true do
        local ped = PlayerPedId()
        if IsPedInAnyVehicle(ped, false) then
            local veh = GetVehiclePedIsIn(ped, false)
            local speed = GetEntitySpeed(veh) * 3.6  -- Convert to km/h
            local rpm = GetVehicleCurrentRpm(veh)
            local gear = GetVehicleCurrentGear(veh)
            local fuel = GetVehicleFuelLevel(veh)

            SendNUIMessage({
                action = 'updateVehicle',
                speed = math.floor(speed),
                rpm = rpm,
                gear = gear,
                fuel = math.floor(fuel)
            })
            Wait(50)
        else
            SendNUIMessage({ action = 'hideVehicle' })
            Wait(500)
        end
    end
end)

HTML और CSS इंटरफ़ेस बनाना

आपके HUD का दृश्य डिज़ाइन यह निर्धारित करता है कि यह गेम में कैसा महसूस होता है। आधुनिक FiveM HUDs साफ, न्यूनतम डिज़ाइन का उपयोग करते हैं जिसमें अर्ध-पारदर्शी पृष्ठभूमि, गोल कोने, और सूक्ष्म एनिमेशन होते हैं। अपनी स्थिति पट्टियों को नीचे-बाएँ कोने में रखें जहाँ वे गेमप्ले में बाधा न डालें, और जब खिलाड़ी ड्राइव कर रहा हो तो स्पीडोमीटर को नीचे-दाएँ कोने में रखें। रंगों के लिए CSS कस्टम प्रॉपर्टीज़ का उपयोग करें ताकि आप कुछ वेरिएबल्स बदलकर पूरे HUD का थीम आसानी से बदल सकें। चिकनी संक्रमणों के साथ एनिमेटेड प्रगति पट्टियाँ HUD को एक परिष्कृत अनुभव देती हैं:

<!-- html/index.html -->
<div id="hud-container">
    <div class="status-bars">
        <div class="bar-wrapper">
            <i class="icon health-icon"></i>
            <div class="bar">
                <div class="bar-fill health-fill" id="health-bar"></div>
            </div>
        </div>
        <div class="bar-wrapper">
            <i class="icon armor-icon"></i>
            <div class="bar">
                <div class="bar-fill armor-fill" id="armor-bar"></div>
            </div>
        </div>
        <div class="bar-wrapper">
            <i class="icon hunger-icon"></i>
            <div class="bar">
                <div class="bar-fill hunger-fill" id="hunger-bar"></div>
            </div>
        </div>
        <div class="bar-wrapper">
            <i class="icon thirst-icon"></i>
            <div class="bar">
                <div class="bar-fill thirst-fill" id="thirst-bar"></div>
            </div>
        </div>
    </div>
    <div class="speedometer" id="speedometer" style="display:none">
        <div class="speed-value" id="speed-value">0</div>
        <div class="speed-unit">KM/H</div>
        <div class="fuel-bar">
            <div class="fuel-fill" id="fuel-bar"></div>
        </div>
    </div>
</div>

CSS के लिए, उपयोग करें transition बार की चौड़ाई पर स्मूद फिल एनिमेशन बनाने के लिए, और लागू करें pointer-events: none पूरे HUD कंटेनर को ताकि यह गेम इनपुट में हस्तक्षेप न करे। प्रत्येक स्थिति बार के लिए विभिन्न रंग खिलाड़ियों को जल्दी से पहचानने में मदद करते हैं कि कौन सा संसाधन कम है बिना लेबल पढ़े। स्वास्थ्य के लिए लाल, कवच के लिए नीला, भूख के लिए नारंगी, और प्यास के लिए सियान एक व्यापक रूप से अपनाई गई परंपरा है जिसे खिलाड़ी सहज रूप से समझते हैं।

जावास्क्रिप्ट संदेश हैंडलिंग

JavaScript परत Lua क्लाइंट से संदेश प्राप्त करती है और DOM को तदनुसार अपडेट करती है। एक संदेश इवेंट लिसनर पंजीकृत करें जो payload में action फ़ील्ड के आधार पर डिस्पैच करता है। अपना अपडेट लॉजिक हल्का रखें क्योंकि यह उस आवृत्ति पर चलता है जिस पर आपके Lua थ्रेड डेटा भेजते हैं, और JavaScript परत में कोई भी विलंब सीधे दृश्य हकलाने में बदल जाता है। अपडेट हैंडलर के अंदर DOM क्वेरी से बचें, तत्व संदर्भों को प्रारंभ में कैश करके:

// html/script.js
const elements = {
    healthBar: document.getElementById('health-bar'),
    armorBar: document.getElementById('armor-bar'),
    hungerBar: document.getElementById('hunger-bar'),
    thirstBar: document.getElementById('thirst-bar'),
    speedometer: document.getElementById('speedometer'),
    speedValue: document.getElementById('speed-value'),
    fuelBar: document.getElementById('fuel-bar')
};

window.addEventListener('message', (event) => {
    const data = event.data;

    switch (data.action) {
        case 'updateStatus':
            elements.healthBar.style.width = data.health + '%';
            elements.armorBar.style.width = data.armor + '%';
            elements.hungerBar.style.width = data.hunger + '%';
            elements.thirstBar.style.width = data.thirst + '%';

            // Color shift when low
            if (data.health < 25) {
                elements.healthBar.classList.add('critical');
            } else {
                elements.healthBar.classList.remove('critical');
            }
            break;

        case 'updateVehicle':
            elements.speedometer.style.display = 'flex';
            elements.speedValue.textContent = data.speed;
            elements.fuelBar.style.width = data.fuel + '%';
            break;

        case 'hideVehicle':
            elements.speedometer.style.display = 'none';
            break;
    }
});

एक CSS क्लास जोड़ें जो बार पर पल्सिंग एनीमेशन ट्रिगर करती है, जो खिलाड़ी का ध्यान तब आकर्षित करती है जब उनकी हेल्थ या भूख खतरनाक रूप से कम हो जाती है। इस तरह का विज़ुअल फीडबैक खिलाड़ियों को लगातार अपनी स्थिति की संख्या देखने पर निर्भर रहने से कहीं अधिक प्रभावी होता है, और यह एक ऐसा परिष्कार जोड़ता है जो शौकिया HUDs को पेशेवर HUDs से अलग करता है।

मिनीमैप अनुकूलन

डिफ़ॉल्ट GTA मिनीमैप कार्यात्मक है लेकिन अधिकांश कस्टम HUD डिज़ाइनों के साथ दृश्य रूप से मेल नहीं खाता। FiveM आपको देशी फ़ंक्शंस के माध्यम से मिनीमैप की स्थिति, आकार, आकार, और ज़ूम स्तर पर नियंत्रण देता है। आप एक गोल मिनीमैप बना सकते हैं, इसे अपने HUD लेआउट के अनुसार स्थानांतरित कर सकते हैं, या इसे पूरी तरह से छिपा सकते हैं और इसे एक कस्टम समाधान से बदल सकते हैं। सबसे आम तरीका मिनीमैप को आपके HUD की सौंदर्यशास्त्र के पूरक के रूप में आकार देना है जबकि अंतर्निहित गेम मैप कार्यक्षमता को बरकरार रखना है:

CreateThread(function()
    -- Wait for map to load
    Wait(500)

    -- Set minimap shape and position
    local minimapHandle = RequestScaleformMovie('MINIMAP')
    SetMinimapClipType(1)  -- 0 = rectangle, 1 = circle

    -- Adjust minimap position and size
    local defaultAspect = 1920 / 1080
    local resX, resY = GetActiveScreenResolution()
    local aspect = resX / resY
    local ratio = defaultAspect / aspect

    SetMinimapComponentPosition('minimap', 'L', 'B',
        0.0, -0.032, 0.145 * ratio, 0.210)
    SetMinimapComponentPosition('minimap_mask', 'L', 'B',
        0.0, 0.032, 0.128 * ratio, 0.300)
    SetMinimapComponentPosition('minimap_blur', 'L', 'B',
        -0.01, -0.032, 0.272 * ratio, 0.420)

    -- Hide default health and armor bars
    local minimap = RequestScaleformMovie('MINIMAP')
    while not HasScaleformMovieLoaded(minimap) do Wait(0) end

    while true do
        -- Disable default HUD components
        HideHudComponentThisFrame(6)  -- Vehicle name
        HideHudComponentThisFrame(7)  -- Area name
        HideHudComponentThisFrame(8)  -- Vehicle class
        HideHudComponentThisFrame(9)  -- Street name
        Wait(0)
    end
end)

जब मिनीमैप को अनुकूलित करते हैं, तो हमेशा विभिन्न स्क्रीन आस्पेक्ट अनुपातों का ध्यान रखें। एक मिनीमैप जो 16:9 डिस्प्ले पर बिल्कुल सही दिखता है, वह अल्ट्रावाइड मॉनिटरों पर खिंचा हुआ या गलत स्थिति में होगा। डिफ़ॉल्ट और वास्तविक आस्पेक्ट अनुपात के बीच अनुपात की गणना करें और इसे चौड़ाई घटकों पर लागू करें। अपने मिनीमैप का परीक्षण कम से कम तीन सामान्य रिज़ॉल्यूशनों (1920x1080, 2560x1440, और 3440x1440) पर करें ताकि विभिन्न खिलाड़ी सेटअप में सुसंगत स्थिति सुनिश्चित हो सके।

डिफ़ॉल्ट GTA HUD तत्व छिपाना

जब आप कस्टम HUD बनाते हैं, तो आपको डिफ़ॉल्ट GTA तत्वों को छिपाना होगा जिन्हें आपका कस्टम UI प्रतिस्थापित करता है, अन्यथा खिलाड़ी डुप्लिकेट जानकारी देखेंगे। FiveM प्रदान करता है HideHudComponentThisFrame() native इस उद्देश्य के लिए, लेकिन इसे हर फ्रेम कॉल करना चाहिए क्योंकि GTA हर टिक पर HUD घटकों को पुनः सक्षम करता है। घटक आईडी में वांछित सितारों से लेकर नकद प्रदर्शन और हथियार व्हील तक सब कुछ शामिल है। पूर्ण प्रतिस्थापन HUD के लिए, आप आमतौर पर स्वास्थ्य बार, आर्मर बार, नकद प्रदर्शन, और वाहन संकेतकों को छिपाना चाहते हैं जबकि आवश्यक तत्व जैसे उपशीर्षक और नोटिफिकेशन पॉपअप्स को दृश्यमान रखना चाहते हैं। एक कॉन्फ़िगर करने योग्य घटक आईडी तालिका बनाएं ताकि सर्वर मालिक बिना आपके कोड को संशोधित किए डिफ़ॉल्ट तत्वों को छिपा सकें। इसके अलावा, उपयोग करें DisplayRadar(false) यदि आपका HUD अपना खुद का मिनीमैप प्रतिस्थापन शामिल करता है, लेकिन ध्यान रखें कि रडार छुपाने से पॉज मेनू मैप भी अक्षम हो जाता है जब तक कि आप पॉज मेनू का पता चलने पर इसे पुनः सक्षम न करें।

प्रदर्शन सर्वोत्तम प्रथाएँ

HUD प्रदर्शन महत्वपूर्ण है क्योंकि आपका HUD लगातार चलता रहता है जब खिलाड़ी गेम में होता है, जिससे छोटी-छोटी अक्षमताएं लंबे खेल सत्रों में स्पष्ट फ्रेम ड्रॉप में बदल जाती हैं। सबसे प्रभावशाली अनुकूलन आपकी अपडेट आवृत्ति को नियंत्रित करना है। धीरे-धीरे बदलने वाले स्टेटस बार जैसे भूख और प्यास हर 500 मिलीसेकंड या यहां तक कि हर सेकंड अपडेट हो सकते हैं, जबकि तेज़ी से बदलने वाले मान जैसे गति को अधिक बार अपडेट करने की आवश्यकता होती है। केवल तभी NUI संदेश भेजने के लिए कंडीशनल रेंडरिंग का उपयोग करें जब मान वास्तव में बदलें, बजाय इसके कि एक ही डेटा को बार-बार पुश करें। जावास्क्रिप्ट पक्ष पर, बचें innerHTML अपडेट्स के लिए क्योंकि यह ब्राउज़र को HTML को पुनः पार्स करने के लिए मजबूर करता है, और उपयोग करें textContent या सीधे स्टाइल प्रॉपर्टी परिवर्तन। उन तत्वों पर CSS एनिमेशन को न्यूनतम करें जो अक्सर अपडेट होते हैं क्योंकि ब्राउज़र का एनिमेशन इंजन और आपका JavaScript अपडेट टकरा सकते हैं, जिससे दृश्य गड़बड़ी हो सकती है। यदि आपका HUD कस्टम फोंट का उपयोग करता है, तो फॉन्ट फाइल लोड होने पर लेआउट शिफ्ट से बचने के लिए उन्हें अपने HTML हेड में प्रीलोड करें। अंत में, अपने संसाधन का प्रोफाइल FiveM के अंतर्निहित resmon कमांड और अपने HUD के लिए लक्ष्य रखें कि प्रति फ्रेम औसतन 0.1ms से कम समय लें, जिससे क्लाइंट पर चल रहे दर्जनों अन्य संसाधनों के लिए जगह बची रहे।

शुरू करने के लिए तैयार?

हमारी शॉप से स्क्रिप्ट लें, या सपोर्ट, अपडेट और आगे आने वाली चीज़ों की झलक के लिए Discord से जुड़ें।