FiveM AI NPC व्यवहार: स्मार्ट NPCs के लिए स्क्रिप्टिंग
अपने FiveM NPCs को जीवंत बनाएं। टास्क सिक्वेंस, पाथफाइंडिंग, प्रतिक्रियाशील संवाद और AI ट्रिक्स से अधिक इमर्सिव रोलप्ले वर्ल्ड बनाएं।
Agency Scripts
Agency Scripts के संस्थापक और प्रमुख डेवलपर
कस्टम NPC AI क्यों महत्वपूर्ण है
डिफ़ॉल्ट GTA V में सामान्य आबादी एकल खिलाड़ी अनुभव के लिए डिज़ाइन की गई है, न कि डूबावपूर्ण रोलप्ले के लिए। NPC बिना उद्देश्य के चलते हैं, खिलाड़ी क्रियाओं पर अप्रत्याशित प्रतिक्रिया देते हैं, और उनके आसपास के रोलप्ले संदर्भ की कोई समझ नहीं होती। एक दुकान क्लर्क स्थिर खड़ा रहता है, एक बारटेंडर काउंटर के पीछे कुछ नहीं करता, और पैदल यात्री सक्रिय अपराध दृश्यों की अनदेखी करते हैं। कस्टम NPC AI इन कार्डबोर्ड कटआउट्स को विश्वसनीय पात्रों में बदल देता है जो डूबाव को बढ़ाते हैं। एक अच्छी तरह से स्क्रिप्टेड दुकानदार वास्तव में रजिस्टर के पीछे खड़ा होता है और ग्राहकों का स्वागत करता है। सुरक्षा गार्ड निर्दिष्ट मार्गों पर गश्त करते हैं और गोलीबारी पर प्रतिक्रिया देते हैं। गैंग सदस्य अपने क्षेत्र की रक्षा करते हैं और जब वे अधिक शक्तिशाली होते हैं तो भाग जाते हैं। इस गाइड में, हम NPC व्यवहार को नियंत्रित करने के लिए मुख्य GTA V देशी फ़ंक्शंस को कवर करेंगे, एक टास्क सीक्वेंस सिस्टम बनाएंगे, गश्त मार्ग लागू करेंगे, यथार्थवादी मुकाबला गतिशीलता के लिए संबंध समूह कॉन्फ़िगर करेंगे, और परिदृश्य-आधारित आबादी बनाएंगे जो आपके सर्वर की दुनिया को जीवंत बनाता है।
टास्क सिक्वेंस: NPC व्यवहार की नींव
टास्क सिक्वेंस क्रमानुसार क्रियाओं की सूची होती है जिसे एक पेड क्रम में निष्पादित करता है। व्यक्तिगत टास्क कॉल्स जो एक-दूसरे को रोकते हैं, के विपरीत, टास्क सिक्वेंस प्रत्येक क्रिया के पूरा होने की गारंटी देता है इससे पहले कि अगली शुरू हो। यह जटिल व्यवहारों के लिए आवश्यक है जैसे कि एक सुरक्षा गार्ड जो दरवाजे तक चलता है, उसे खोलता है, कमरे में प्रवेश करता है, और फिर खड़ा गार्ड पोजीशन लेता है। टास्क सिक्वेंस के बिना, आपको मैनुअल स्टेट ट्रैकिंग टाइमर्स के साथ करनी होगी, जो नाजुक और बनाए रखना कठिन है। नेटिव OpenSequenceTask और CloseSequenceTask functions एक अनुक्रम हैंडल बनाते हैं जिसे किसी भी ped को सौंपा जा सकता है TaskPerformSequence.
-- Create a task sequence for a shopkeeper NPC
local function CreateShopkeeperRoutine(ped, counterCoords, counterHeading)
local seq = 0
-- Open a new sequence (pass 0 as reference, it returns a handle)
OpenSequenceTask(seq)
-- Walk to the counter position
TaskGoStraightToCoord(0, counterCoords.x, counterCoords.y, counterCoords.z, 1.0, -1, counterHeading, 0.5)
-- Turn to face customers
TaskAchieveHeading(0, counterHeading, 2000)
-- Play idle animation at counter
TaskStartScenarioInPlace(0, 'PROP_HUMAN_SHOP_INTERACT', 0, true)
CloseSequenceTask(seq)
-- Assign sequence to the ped
TaskPerformSequence(ped, seq)
ClearSequenceTask(seq)
end
-- Usage
local shopkeeper = CreateNPC('s_m_m_shopkeep_01', vector3(25.7, -1347.3, 29.5))
CreateShopkeeperRoutine(shopkeeper, vector3(25.7, -1347.3, 29.5), 270.0)
The Scenario System
परिदृश्य पूर्वनिर्धारित एनीमेशन लूप हैं जो NPCs को वास्तविक गतिविधियाँ करते हुए दिखाते हैं। GTA V में सैकड़ों अंतर्निहित परिदृश्य शामिल हैं जो धूम्रपान और पीने से लेकर ATM का उपयोग करने, डेस्क पर काम करने, या पार्क में पुश-अप करने तक हैं। उपयोग TaskStartScenarioInPlace स्थिर गतिविधियों के लिए या TaskStartScenarioAtPosition स्थिति-विशिष्ट के लिए, आप NPCs को संदर्भानुकूल उपयुक्त क्रियाएं करने के लिए बना सकते हैं। विश्वसनीय परिवेश AI की कुंजी स्थानों के लिए परिदृश्यों को मिलाना है। एक बारटेंडर को उपयोग करना चाहिए WORLD_HUMAN_BARTENDER , एक गैराज में मैकेनिक को WORLD_HUMAN_WELDINGऔर, एक नाइटक्लब के बाहर NPCs को उपयोग करना चाहिए WORLD_HUMAN_SMOKING या WORLD_HUMAN_STAND_MOBILE.
-- Scenario-based ambient NPCs with location awareness
local AmbientNPCs = {
{
model = 'a_m_y_barman_01',
coords = vector4(-561.2, 286.3, 82.2, 270.0),
scenario = 'WORLD_HUMAN_BARTENDER',
invincible = true,
},
{
model = 's_m_y_doorman_01',
coords = vector4(-560.8, 293.5, 82.2, 180.0),
scenario = 'WORLD_HUMAN_GUARD_STAND',
weapon = 'WEAPON_PISTOL',
},
{
model = 'a_f_y_business_01',
coords = vector4(-555.0, 290.1, 82.2, 90.0),
scenario = 'WORLD_HUMAN_STAND_MOBILE',
},
{
model = 's_m_y_ammucity_01',
coords = vector4(22.0, -1105.0, 29.8, 160.0),
scenario = 'PROP_HUMAN_SHOP_INTERACT',
invincible = true,
},
}
local spawnedPeds = {}
local function SpawnAmbientNPCs()
for _, data in ipairs(AmbientNPCs) do
local hash = GetHashKey(data.model)
RequestModel(hash)
while not HasModelLoaded(hash) do Wait(10) end
local ped = CreatePed(4, hash, data.coords.x, data.coords.y, data.coords.z, data.coords.w, false, true)
SetEntityInvincible(ped, data.invincible or false)
SetBlockingOfNonTemporaryEvents(ped, true)
FreezeEntityPosition(ped, false)
if data.weapon then
GiveWeaponToPed(ped, GetHashKey(data.weapon), 250, false, true)
end
TaskStartScenarioInPlace(ped, data.scenario, 0, true)
SetModelAsNoLongerNeeded(hash)
table.insert(spawnedPeds, ped)
end
end
गश्त मार्ग और वेपॉइंट नेविगेशन
गश्त मार्ग NPCs को पूर्वनिर्धारित वेपॉइंट्स के बीच लूप में चलाते हैं, जो सुरक्षा गार्ड, पुलिस अधिकारी और गैंग प्रहरी के लिए आवश्यक है। सबसे सरल तरीका एक दोहराए जाने वाले कार्य अनुक्रम का उपयोग करता है जो पेड को प्रत्येक वेपॉइंट तक ले जाता है, थोड़ी देर रुकता है, फिर अगले पर जाता है। एक अधिक उन्नत तरीका एक स्टेट मशीन का उपयोग करता है जो वर्तमान वेपॉइंट इंडेक्स को ट्रैक करता है और व्यवधानों को सहजता से संभालता है। जब गश्त करता गार्ड खतरे का पता लगाता है, तो उसे गश्त से बाहर निकलना चाहिए, खतरे को संभालना चाहिए, और फिर अपनी अंतिम ज्ञात वेपॉइंट से गश्त फिर से शुरू करनी चाहिए, शुरुआत से नहीं। गश्त प्रणाली को विभिन्न गति, प्रत्येक वेपॉइंट पर वैकल्पिक परिदृश्य क्रियाओं, और कॉन्फ़िगर करने योग्य प्रतीक्षा समय का समर्थन भी करना चाहिए।
-- Patrol route system with state management
local PatrolRoutes = {
police_station_exterior = {
speed = 1.0, -- walking speed
waypoints = {
{ coords = vector3(441.0, -982.0, 30.7), heading = 90.0, wait = 5000, scenario = 'WORLD_HUMAN_GUARD_STAND' },
{ coords = vector3(451.0, -982.0, 30.7), heading = 0.0, wait = 3000 },
{ coords = vector3(451.0, -993.0, 30.7), heading = 270.0, wait = 5000, scenario = 'WORLD_HUMAN_COP_IDLES' },
{ coords = vector3(441.0, -993.0, 30.7), heading = 180.0, wait = 3000 },
}
},
}
local function StartPatrol(ped, routeName)
local route = PatrolRoutes[routeName]
if not route then return end
CreateThread(function()
local waypointIndex = 1
while DoesEntityExist(ped) and not IsEntityDead(ped) do
local wp = route.waypoints[waypointIndex]
-- Walk to waypoint
TaskGoStraightToCoord(ped, wp.coords.x, wp.coords.y, wp.coords.z, route.speed, -1, wp.heading, 0.5)
-- Wait until ped reaches destination
while DoesEntityExist(ped) and not IsEntityDead(ped) do
local dist = #(GetEntityCoords(ped) - wp.coords)
if dist < 1.5 then break end
Wait(500)
end
-- Face the correct direction
TaskAchieveHeading(ped, wp.heading, 1500)
Wait(1500)
-- Play scenario at waypoint if defined
if wp.scenario then
TaskStartScenarioInPlace(ped, wp.scenario, 0, false)
Wait(wp.wait or 5000)
ClearPedTasks(ped)
else
Wait(wp.wait or 3000)
end
-- Move to next waypoint (loop back to 1)
waypointIndex = waypointIndex % #route.waypoints + 1
end
end)
end
रिलेशनशिप समूह और युद्ध व्यवहार
रिलेशनशिप समूह निर्धारित करते हैं कि NPC एक-दूसरे और खिलाड़ियों के प्रति कैसे प्रतिक्रिया करते हैं। डिफ़ॉल्ट रूप से, सभी NPC सामान्य रिलेशनशिप समूहों में होते हैं जिनकी स्थिति तटस्थ होती है, इसलिए गैंग सदस्य एक-दूसरे से नहीं लड़ते और पुलिस अपराधियों का स्वतः पीछा नहीं करती। कस्टम रिलेशनशिप समूह आपको ऐसे गुटीय गतिशीलता बनाने देते हैं जहाँ पुलिस हथियारबंद अपराधियों के प्रति शत्रुतापूर्ण होती है, प्रतिद्वंद्वी गैंग एक-दूसरे पर देखते ही हमला करते हैं, और नागरिक युद्ध से भागते हैं। SetRelationshipBetweenGroups native 0 (साथी) से 3 (तटस्थ) से 5 (घृणा) तक संबंध स्तर स्वीकार करता है, जो नियंत्रित करता है कि पेड लड़ेंगे, भागेंगे, या एक-दूसरे की अनदेखी करेंगे। यह सिस्टम यथार्थवादी गुट युद्ध, क्षेत्रीय विवाद, और कानून प्रवर्तन प्रतिक्रियाओं को बनाने की रीढ़ है।
-- Relationship group setup for faction-based AI
local RelGroups = {}
local function InitRelationshipGroups()
-- Create custom groups
AddRelationshipGroup('GANG_BALLAS', RelGroups)
AddRelationshipGroup('GANG_FAMILIES', RelGroups)
AddRelationshipGroup('GANG_VAGOS', RelGroups)
AddRelationshipGroup('POLICE_CUSTOM', RelGroups)
AddRelationshipGroup('CIVILIAN', RelGroups)
-- Gangs hate rival gangs
SetRelationshipBetweenGroups(5, GetHashKey('GANG_BALLAS'), GetHashKey('GANG_FAMILIES'))
SetRelationshipBetweenGroups(5, GetHashKey('GANG_FAMILIES'), GetHashKey('GANG_BALLAS'))
SetRelationshipBetweenGroups(5, GetHashKey('GANG_BALLAS'), GetHashKey('GANG_VAGOS'))
SetRelationshipBetweenGroups(5, GetHashKey('GANG_VAGOS'), GetHashKey('GANG_BALLAS'))
-- Police dislike all gangs
SetRelationshipBetweenGroups(4, GetHashKey('POLICE_CUSTOM'), GetHashKey('GANG_BALLAS'))
SetRelationshipBetweenGroups(4, GetHashKey('POLICE_CUSTOM'), GetHashKey('GANG_FAMILIES'))
SetRelationshipBetweenGroups(4, GetHashKey('POLICE_CUSTOM'), GetHashKey('GANG_VAGOS'))
-- Civilians flee from gangs
SetRelationshipBetweenGroups(1, GetHashKey('CIVILIAN'), GetHashKey('GANG_BALLAS'))
SetRelationshipBetweenGroups(1, GetHashKey('CIVILIAN'), GetHashKey('GANG_FAMILIES'))
end
-- Assign a ped to a relationship group
local function SetPedFaction(ped, faction)
local groupHash = GetHashKey(faction)
SetPedRelationshipGroupHash(ped, groupHash)
end
भागने और लड़ने का व्यवहार
NPCs के खतरे पर प्रतिक्रिया को नियंत्रित करना इमर्सिव कॉम्बैट परिदृश्यों के लिए महत्वपूर्ण है। डिफ़ॉल्ट GTA V व्यवहार अराजक है: कुछ NPC भागते हैं, कुछ डरते हैं, और हथियारबंद NPC हो सकता है कि लड़ें या न लड़ें। कस्टम कॉम्बैट व्यवहार कॉम्बैट विशेषताओं और कॉन्फ़िगरेशन फ्लैग्स का उपयोग करके पूर्वानुमेय, भूमिका-उपयुक्त प्रतिक्रियाएँ बनाता है। एक गैंग सदस्य खराब सटीकता के साथ लड़ाई करता है, एक प्रशिक्षित सुरक्षा गार्ड कवर लेता है और मध्यम सटीकता के साथ लड़ता है, एक नागरिक तुरंत भाग जाता है, और एक VIP कैरेक्टर झुकता है और मदद के लिए कॉल करता है। SetPedCombatAttributes native व्यक्तिगत व्यवहारों को नियंत्रित करता है जैसे कि पेड कवर का उपयोग कर सकता है, ब्लाइंड फायर कर सकता है, ध्वनियों की जांच कर सकता है, या जब अधिक हथियारबंद हो तो भाग सकता है।
-- Combat behavior presets
local CombatPresets = {
gang_member = function(ped)
SetPedCombatAttributes(ped, 46, true) -- Can fight armed peds on foot
SetPedCombatAttributes(ped, 5, true) -- Can use cover
SetPedCombatAttributes(ped, 2, true) -- Can do drivebys
SetPedCombatAbility(ped, 1) -- Average combat ability
SetPedCombatRange(ped, 1) -- Medium range
SetPedAccuracy(ped, 30) -- Poor accuracy
SetPedFleeAttributes(ped, 0, false) -- Don't flee
SetPedCombatMovement(ped, 2) -- Offensive movement
end,
security_guard = function(ped)
SetPedCombatAttributes(ped, 46, true)
SetPedCombatAttributes(ped, 5, true) -- Use cover
SetPedCombatAttributes(ped, 21, true) -- Investigate dead peds
SetPedCombatAbility(ped, 2) -- Professional
SetPedCombatRange(ped, 2) -- Long range
SetPedAccuracy(ped, 60) -- Good accuracy
SetPedCombatMovement(ped, 1) -- Defensive movement
end,
civilian = function(ped)
SetPedFleeAttributes(ped, 2, true) -- Flee immediately
SetPedCombatAttributes(ped, 17, true) -- Can be scared
SetPedCombatAttributes(ped, 46, false) -- Cannot fight
SetPedCombatAbility(ped, 0) -- Poor fighter
end,
}
-- Apply a combat preset
local function ApplyCombatPreset(ped, presetName)
local preset = CombatPresets[presetName]
if preset then preset(ped) end
end
NPC जीवनचक्र और प्रदर्शन प्रबंधन
NPCs को स्पॉन करना सर्वर और क्लाइंट प्रदर्शन पर सीधे प्रभाव डालता है। हर सक्रिय पेड AI प्रोसेसिंग, भौतिकी सिमुलेशन, और नेटवर्क सिंक्रोनाइज़ेशन के लिए CPU चक्रों का उपभोग करता है। एक सरल कार्यान्वयन जो सर्वर शुरू होने पर सभी NPCs को स्पॉन करता है और उन्हें स्थायी रूप से जीवित रखता है, जैसे-जैसे जनसंख्या बढ़ती है प्रदर्शन को प्रभावित करेगा। सही तरीका निकटता-आधारित स्पॉनिंग है जहाँ NPCs केवल तब बनाए जाते हैं जब कोई खिलाड़ी एक कॉन्फ़िगर करने योग्य सीमा के भीतर होता है और जब सभी खिलाड़ी क्षेत्र छोड़ देते हैं तो उन्हें हटाया जाता है। एक स्पैटियल पार्टिशनिंग सिस्टम का उपयोग करें जो मानचित्र को ज़ोन में विभाजित करता है और केवल उन ज़ोन के लिए NPC लॉजिक प्रोसेस करता है जहाँ निकट के खिलाड़ी होते हैं। पेड हैंडल को कैश करें और जब संभव हो उन्हें पुन: उपयोग करें बजाय हर बार खिलाड़ी ज़ोन में प्रवेश और निकास पर NPCs को हटाने और पुनः बनाने के। सेट करें SetEntityAsMissionEntity को false पर सेट करें और नेटवर्क-सचेत निर्माण फ़्लैग्स का उपयोग करें ताकि गेम इंजन अपने स्ट्रीमिंग सिस्टम के भीतर पैड जीवनचक्र को स्वाभाविक रूप से प्रबंधित कर सके।
-- Proximity-based NPC spawner with zone management
local SPAWN_RANGE = 80.0
local DESPAWN_RANGE = 120.0
local activeZones = {}
CreateThread(function()
while true do
local playerCoords = GetEntityCoords(PlayerPedId())
for zoneName, zone in pairs(NPCZones) do
local dist = #(playerCoords - zone.center)
if dist < SPAWN_RANGE and not activeZones[zoneName] then
-- Spawn zone NPCs
activeZones[zoneName] = SpawnZoneNPCs(zone)
elseif dist > DESPAWN_RANGE and activeZones[zoneName] then
-- Despawn zone NPCs
for _, ped in ipairs(activeZones[zoneName]) do
if DoesEntityExist(ped) then
DeleteEntity(ped)
end
end
activeZones[zoneName] = nil
end
end
Wait(2000) -- Check every 2 seconds
end
end)
सभी को एक साथ लाना
एक प्रोडक्शन NPC AI सिस्टम इन सभी तत्वों को एक सुसंगत फ्रेमवर्क में जोड़ता है जो कॉन्फ़िगरेशन डेटा द्वारा संचालित होता है। आपके कॉन्फ़िग में प्रत्येक NPC परिभाषा मॉडल, स्पॉन स्थान, व्यवहार प्रकार (स्थिर, गश्ती, सुरक्षा), कॉम्बैट प्रीसेट, संबंध समूह, और कोई भी परिदृश्य या कार्य अनुक्रम निर्दिष्ट करती है। फ्रेमवर्क इन परिभाषाओं को लोड करता है, खिलाड़ी की निकटता के आधार पर स्पॉनिंग और डिस्पॉनिंग का प्रबंधन करता है, जब NPC कॉम्बैट या खिलाड़ी इंटरैक्शन से बाधित होते हैं तो स्थिति संक्रमण संभालता है, और जब NPC की आवश्यकता नहीं होती तो संसाधनों को साफ करता है। सबसे महत्वपूर्ण डिज़ाइन सिद्धांत डेटा को लॉजिक से अलग करना है: सभी NPC व्यवहार को बिना कोड परिवर्तन के कॉन्फ़िगर किया जाना चाहिए, जिससे सर्वर मालिक केवल कॉन्फ़िग फ़ाइलों के माध्यम से नए NPC जोड़ सकते हैं, गश्ती मार्गों को संशोधित कर सकते हैं, और कॉम्बैट पैरामीटर समायोजित कर सकते हैं। यह डेटा-संचालित दृष्टिकोण आपके AI सिस्टम को कुछ क्वेस्ट NPC से लेकर पूरे शहर में सैकड़ों परिवेशीय पात्रों तक बिना अंतर्निहित कोड में वास्तुकला परिवर्तन के स्केल करने की अनुमति देता है।