[HELP] TaskPlayAnim with npc

Hello everyone, I need help with this script.

The purpose of the script is to spawn npc and when the player approaches the npc, it makes an animation.
The code works but when we have more than 1 npc, it no longer works, the spawn of npc work but no longer do any actions.

for example.

When we have 1 npc spawned:

  • Everything goes well, it does its actions in the approach of the player and when it goes away.

when we have more than 1 npc spawned:

  • The npc normally appears but does not perform his basic animation, and doesn’t react to the player’s approach.
  • Same when the player goes away.

code here:

– local params

local generalPed
local generalLoaded = false

local PlayingAnim = false

– position for spawning NPC

local general_peds = {
	{x=-2511.16479492188, y=3616.90478515625, z=13.6422147750854, a=245.000457763672},
	{x=24.392505645752, y=-1345.41369628906, z=29.4970207214355, a=264.900115966797},
}

– spawning NPC here

Citizen.CreateThread(function()
  while true do
    Citizen.Wait(0)
	
	if (not generalLoaded) then
	  
	  for k,v in ipairs(general_peds) do
        RequestModel(GetHashKey("mp_m_shopkeep_01"))
        while not HasModelLoaded(GetHashKey("mp_m_shopkeep_01")) do
          Wait(1)
        end
		
        generalPed = CreatePed(2, "mp_m_shopkeep_01", v.x, v.y, v.z, v.a, false, false)
        SetPedFleeAttributes(generalPed, 0, 0)
		
      end
      generalLoaded = true
		
    end
	
  end
end)

– Near NPC function

function IsNearNPC()
  local ply = GetPlayerPed(-1)
  local plyCoords = GetEntityCoords(ply, 0)
  for _, item in pairs(general_peds) do
    local distance = GetDistanceBetweenCoords(item.x, item.y, item.z,  plyCoords["x"], plyCoords["y"], plyCoords["z"], true)
    if(distance < 6) then
      return true
    end
  end
end

– do TaskPlayAnim (work only when just have 1 NPC)

Citizen.CreateThread(function()
	while true do
		Citizen.Wait(0)
		
		RequestAnimDict("random@shop_gunstore")
		while (not HasAnimDictLoaded("random@shop_gunstore")) do 
			Citizen.Wait(0) 
		end
		
		if (IsNearNPC()) then
			if (PlayingAnim == false) then
				TaskPlayAnim(generalPed,"random@shop_gunstore","_greeting", 1.0, -1.0, 4000, 0, 1, true, true, true)
				PlayingAnim = true
				Citizen.Wait(4000)
			else
				TaskPlayAnim(generalPed,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
			end
		else
			TaskPlayAnim(generalPed,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
			PlayingAnim = false
		end
		
	end
end)

I want every npc to perform their action but I don’t know where the problem comes from.
thanks for your help.

Each time you spawn a new ped with “generalPed” the latest will get the id

There is no solution to this?

maybe

local general_peds = {
{hash = "mp_m_shopkeep_01", x=-2511.16479492188, y=3616.90478515625, z=13.6422147750854, a=245.000457763672},
{hash = "mp_m_shopkeep_01",  x=24.392505645752, y=-1345.41369628906, z=29.4970207214355, a=264.900115966797},
}
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)

if (not generalLoaded) then

     for k,v in pairs(general_peds) do
        RequestModel(GetHashKey(v.hash))
        while not HasModelLoaded(GetHashKey(v.hash)) do
          Wait(1)
        end

    generalPed = CreatePed(2, v.hash, v.x, v.y, v.z, v.a, false, false)
    SetPedFleeAttributes(generalPed, 0, 0)
    TaskPlayAnim(generalPed,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
  end
  generalLoaded = true

end
end
end)
function playingAnimation()
 local PlayingAnim = not PlayingAnim
end
function getShopKeeper()
local ply = GetPlayerPed(-1)
local plyCoords = GetEntityCoords(ply, 0)
    for k,v in pairs(general_peds) do
        local shopKeep = GetClosestPed(v.x v.y, v.z, 20.05, 1, 0, 0, 0, -1)
        local distance = GetDistanceBetweenCoords(v.x, v.y, v.z, plyCoords["x"], plyCoords["y"], plyCoords["z"], true)
       if distance < 6 then
           TaskPlayAnim(shopKeep,"random@shop_gunstore","_greeting", 1.0, -1.0, 4000, 0, 1, true, true, true)
       else
           TaskPlayAnim(shopKeep,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
       end
    end
end
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)

	RequestAnimDict("random@shop_gunstore")
	while (not HasAnimDictLoaded("random@shop_gunstore")) do 
		Citizen.Wait(0) 
	end
		if (PlayingAnim == false) then
			getShopKeeper()
			playingAnimation()
			Citizen.Wait(4000)
		end
		
playingAnimation()
end
end)

i just did this really quickly and i really suck at lua as it’s my first language and i started like a few weeks ago but i think it might be something along these lines.

send the created peds to an array so you still have access to them, else the name “generalPed” is not unique.

I am a beginner in lua, how could I do this?

I tried the changes with the GetClosestPed but it doesn’t work :confused:

https://www.lua.org/pil/11.1.html
https://www.lua.org/pil/19.2.html

And as JinkLeft said

local general_Peds = {
{hash = "mp_m_shopkeep_01", x=-2511.16479492188, y=3616.90478515625, z=13.6422147750854, a=245.000457763672},
{hash = "mp_m_shopkeep_01",  x=24.392505645752, y=-1345.41369628906, z=29.4970207214355, a=264.900115966797},
}

= An array of shopkeepers
To access the second one, you’d do general_Peds[2]
Have you tried his code?

I tried, that doesn’t give any result, NPCs appear but do nothing and The given code by JinkLeft doesn’t work :confused:

this part of code:

local shopKeep = GetClosestPed(v.x v.y, v.z, 20.05, 1, 0, 0, 0, -1)

(NPC doesn’t appears)

i tryed this but still doesn’t work
– Array

general_peds = {
	{"mp_m_shopkeep_01", -2511.16479492188, 3616.90478515625, 13.6422147750854, 245.000457763672},
	{"mp_m_shopkeep_01", 24.392505645752, -1345.41369628906, 29.4970207214355, 264.900115966797},
}

–

   Citizen.CreateThread(function()
   while true do
   Citizen.Wait(0)

        RequestAnimDict("random@shop_gunstore")
		while (not HasAnimDictLoaded("random@shop_gunstore")) do 
			Citizen.Wait(0) 
		end
		
		local ply = GetPlayerPed(-1)
		local plyCoords = GetEntityCoords(ply, 0)
		for i=1, #general_peds do
			PedCoords = general_peds[i] 
			
			local distance = GetDistanceBetweenCoords(PedCoords[2], PedCoords[3], PedCoords[4], plyCoords["x"], plyCoords["y"], plyCoords["z"], true)
			if distance < 6 then
				if (PlayingAnim == false) then
					TaskPlayAnim(generalPed,"random@shop_gunstore","_greeting", 1.0, -1.0, 4000, 0, 1, true, true, true)
					PlayingAnim = true
					Citizen.Wait(4000)
				else
					TaskPlayAnim(generalPed,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
				end
			else
				TaskPlayAnim(generalPed,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
				PlayingAnim = false
		        end
            end
       end
    end)
local pos = GetEntityCoords(GetPlayerPed(-1))
local heading = GetEntityHeading(GetPlayerPed(-1))

local ShopClerk = {
	{modelHash = 416176080},
	{modelHash = 416176080},
	{modelHash = 416176080},
	{modelHash = 416176080},
	{modelHash = 416176080},
}

	RequestModel(416176080)
    while not HasModelLoaded(416176080) do
      Wait(1)
    end

	i = math.random(1,5)
	CreatePed(2, ShopClerk[i].modelHash, pos.x, pos.y, pos.z, heading, true)

Add an ID and and apply animations and what not through that.
Also, mark your code and click the < / > button before you post please, makes it alot easier to read.

nothing change, NPC doesn’t do his action when player approach him.

Normally, the NPC must say hello to the player’s approach and chain another animation (like the NPC in gta online {ammunation}).
when I have more than 1 line in array general_peds, it does not work anymore.

script work whis this

local general_peds = {
	{-2511.16479492188, 3616.90478515625, 13.6422147750854, 245.000457763672},
}

script work but animation doesn’t work:

local general_peds = {
	{-2511.16479492188, 3616.90478515625, 13.6422147750854, 245.000457763672},
	{24.392505645752, -1345.41369628906, 29.4970207214355, 264.900115966797},
}

I tried your suggestions, but nothing changes
The final objective is to make appear npc in their respective shops and when the player enters, the npc say hello.

try this, not tested though.

ShopClerk = {
	{id = 1, modelHash = 416176080, x = -210.610, y = -1007.502, z = 29.157, heading = 0.0}, 
	{id = 2, modelHash = 416176080, x = -210.610, y = -1007.502, z = 29.157, heading = 50.0},
	{id = 3, modelHash = 416176080, x = -210.610, y = -1007.502, z = 29.157, heading = 120.0},
	{id = 4, modelHash = 416176080, x = -210.610, y = -1007.502, z = 29.157, heading = 150.0},
	{id = 5, modelHash = 416176080, x = -210.610, y = -1007.502, z = 29.157, heading = 250.0},
}

i = math.random(1,5)

RegisterNetEvent("Clerk")
AddEventHandler("Clerk", function()
	RequestModel(416176080)
    while not HasModelLoaded(416176080) do
      Wait(1)
    end

	CreatePed(2, ShopClerk[i].modelHash, ShopClerk[i].x, ShopClerk[i].y, ShopClerk[i].z, ShopClerk[i].heading, true)
end)

Citizen.CreateThread(function()
	while true do
		Citizen.Wait(0)
		RequestAnimDict("random@shop_gunstore")
		while (not HasAnimDictLoaded("random@shop_gunstore")) do 
			Citizen.Wait(0) 
		end

		if GetDistanceBetweenCoords(ShopClerk[i].x, ShopClerk[i].y, ShopClerk[i].z, GetEntityCoords(GetPlayerPed(-1))) < 2.5 then
			TaskPlayAnim(ShopClerk[i].id,"random@shop_gunstore","_greeting", 1.0, -1.0, 4000, 0, 1, true, true, true)
		end
	end
end)
1 Like

I made some changes and the script work ! thank for your help !
There is just a slight problem, the animation “say hello” is played in loop and When I delete “Citzen.Wait(4000)”, the animation is not played :confused:

code:

local generalLoaded = false
local playingAnimation = false

local ShopClerk = {
	{id = 1, modelHash = "mp_m_shopkeep_01", x = -2511.16479492188, y = 3616.90478515625, z = 13.6422147750854, heading = 245.000457763672}, 
	{id = 2, modelHash = "mp_m_shopkeep_01", x = 24.392505645752, y = -1345.41369628906, z = 29.4970207214355, heading = 264.900115966797},
	{id = 3, modelHash = "mp_m_shopkeep_01", x = -47.3110542297363, y = -1758.62475585938, z = 29.4209995269775, heading = 48.1558074951172},
	{id = 4, modelHash = "mp_m_shopkeep_01", x = -2504.181640625, y = 3599.275390625, z = 14.4641599655151, heading = 146.33984375},
}


Citizen.CreateThread(function()
  while true do
    Citizen.Wait(0)
	
	playerPed = GetPlayerPed(-1)
    playerCoords = GetEntityCoords(playerPed, 0)
	
	if (not generalLoaded) then
		for i=1, #ShopClerk do
			RequestModel(ShopClerk[i].modelHash)
			while not HasModelLoaded(ShopClerk[i].modelHash) do
			  Wait(1)
			end

			ShopClerk[i].id = CreatePed(2, ShopClerk[i].modelHash, ShopClerk[i].x, ShopClerk[i].y, ShopClerk[i].z, ShopClerk[i].heading, true)
		end
		
		generalLoaded = true
    end

	RequestAnimDict("random@shop_gunstore")
	while (not HasAnimDictLoaded("random@shop_gunstore")) do 
		Citizen.Wait(0) 
	end
		
		for i=1, #ShopClerk do
			local distance = GetDistanceBetweenCoords(ShopClerk[i].x, ShopClerk[i].y, ShopClerk[i].z, GetEntityCoords(GetPlayerPed(-1)))
			if distance < 6 then
				if (PlayingAnim == false) then
					TaskPlayAnim(ShopClerk[i].id,"random@shop_gunstore","_greeting", 1.0, -1.0, 4000, 0, 1, true, true, true)
					PlayingAnim = true
					Citizen.Wait(4000)
				else
					TaskPlayAnim(ShopClerk[i].id,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
				end
			else
				TaskPlayAnim(ShopClerk[i].id,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
				PlayingAnim = false
			end
			
			
		end
	end
end)

Cancel the task after the wait
ClearPedTasks()

The animation still run :confused:
The npc stop his task and resumes it.

try making a new variable like

		if distance < 6 and lulz == false then
			if PlayingAnim == false then
					TaskPlayAnim(ShopClerk[i].id,"random@shop_gunstore","_greeting", 1.0, -1.0, 4000, 0, 1, true, true, true)
					PlayingAnim = true
					Citizen.Wait(4000)
					lulz = true
				else
					TaskPlayAnim(ShopClerk[i].id,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
				end
			else
				TaskPlayAnim(ShopClerk[i].id,"random@shop_gunstore","_idle_b", 1.0, -1.0, -1, 0, 1, true, true, true)
				PlayingAnim = false
			end

Should force the loop to end, it is currently looping as distance is always < 6, or does it stop when you walk away?

local lulz = false and your suggestion, the script work, thank you :slight_smile:

edit: not working lol, i can’t set lulz to false
when i set lulz to false the loop is still here

1 Like
if distance > 6 then
	lulz = false
end
 if distance > 6 then
	lulz = false
 end

still loop animation
I think the problem comes from “distance”

Does it stop when you are further way?

And what if you set the duration in TaskPlayAnim() to 0, and end it after Wait(4000) with ClearPedTasks()?