Hi everyone, i’m currently trying to create a simple AI like the one in Retail Tycoon where NPCs will walk around a definied map and eventually look at some shelf, paints and so on.
The problem is that i almost have 0 experience in AI and Pathfinding and the tutorials on Youtube or Devforum don’t really help.
This is the script i’ve made so far and works fine with only 1 NPC active
NPC = Workspace.NPC.NPC1
NPC_Humanoid = NPC.Humanoid
Destinations = workspace.Waypoints:GetChildren()
Path = PS:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = false,
})
Path:ComputeAsync(NPC.HumanoidRootPart.Position,Destinations[math.random(1,#Destinations)].Position)
Waypoint = Path:GetWaypoints()
NextWaypoint = NPC_Humanoid.MoveToFinished:Connect(function(reached)
if i < #Waypoint then
NPC_Humanoid:MoveTo(Waypoint[i].Position)
i += 1
else
Path:ComputeAsync(NPC.HumanoidRootPart.Position,Destinations[math.random(1,#Destinations)].Position)
Waypoint = Path:GetWaypoints()
i=1
NPC_Humanoid:MoveTo(Waypoint[i].Position)
end
end)
i = 1
NPC_Humanoid:MoveTo(Waypoint[i].Position)
the problem is when i try to add more NPCs, the Waypoint output will simply be an empty table and will compute the waypoints for only the first one
for i,v in ipairs(workspace.NPC:GetChildren()) do
NPC_Humanoid = v.Humanoid
Destinations = workspace.Destinations:GetChildren()
Path = PS:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = false,
})
Path:ComputeAsync(v.HumanoidRootPart.Position,Destinations[1].Position)
Waypoint = Path:GetWaypoints()
print(Waypoint)
end
Output will be
{…} (Table of positions)
{} (Just nothing)
Does anyone know how to fix or where to start to create something like this?
Thanks in advance
Here is what I recommend doing, using coroutines for every NPC so that each and every NPC can run at the same time with one script. Here is a short script that effectively uses it:
I do think the reason why the waypoint table was empty was a localization error but hopefully this helps with your understanding!
First we get the variables:
local NPC_Folder = -- The foder of NPC's you want to use, put a :GetChildren() at the end of this
local Destination_Folder = -- Same thing but with destinations
local ps = game:GetService("PathfindingService") -- Serivices
local path = ps:CreatePath()
Next we create two functions:
local function setNPCOwnerShip(model) -- I recommend this, for some reason pathfinding is laggy if not
for _, object in pairs(model:GetChildren()) do
if object:IsA("BasePart") then
object:SetNetworkOwner()
end
end
end
local function initalizeNPCStatus() -- Next we iterate through all NPC's with one goal
local status = {} -- To create a status list of who is and who isn't pathfinding
for index, npc in pairs(NPC_Folder) do
status[index] = false
setNPCOwnerShip(npc)
end
return status -- I don't know if status is a key word but if it is just change it easily
end
Lastly is the main code:
local statuses = initalizeNPCStatus() -- We use that function, you will have to make a code that runs
-- this everytime a new NPC is added to that folder
while wait() do
for index, npc in pairs(NPC_Folder) do
coroutine.wrap(function() -- Just so all other npcs can run at the same time
if statuses[index] == false then
statuses[index] = true
local chosenDestination = math.random(1, #Destination_Folder)
local hrp = npc.HumanoidRootPart.Position
local hum = npc.Humanoid
-- Pathfinding
path:ComputeAsync(hrp, Destination_Folder[chosenDestination].Position)
local waypoints = path:GetWaypoints()
for i, waypoint in pairs(waypoints) do
hum:MoveTo(waypoint.Position)
hum.MoveToFinished:Wait()
end
statuses[index] = false
end
end)()
end
end
Thank you so much, this is exactly what i was trying to make, i will surely edit it and dissect the script to fully understand how it works, just one question, i’ve noticed that when starting all NPCs walk to the same first end point before spreading, is not a problem about it, i can simply make it simulate a bit before showing to the player but just curious of why does it this way even with different end point chosen
I noticed that too when running it, it actually is an easy fix! Just move the right before the pathfinding script into the coroutine function.
local path = ps:CreatePath()
-- Put this ^ before this v it should be at the beginning
path:ComputeAsync(hrp, Destination_Folder[chosenDestination].Position)
local waypoints = path:GetWaypoints()
That was my mistake because the path variable is being altered and used by all the Npc’s rather than each Npc individually