So i have these npcs when it spawns to go to a spot, and if they touch that spot that area “occupied” attribute is turned true, i got everything else working except it doesnt check it if its already occupied and then finds another spot that isnt occupied.
local pfs = game:GetService("PathfindingService")
local NPC = script.Parent
local debri = game:GetService("Debris")
local waitpoints = workspace:WaitForChild("Areas"):GetChildren()
local randomdes = waitpoints[math.random(1, #waitpoints)]
-- Change Destination1 to the name of your destination part and delete this message if you want
local path = pfs:CreatePath()
task.wait(0.5)
path:ComputeAsync(NPC.HumanoidRootPart.Position,randomdes.Position)
for _, waypoint in pairs(path:GetWaypoints()) do
if randomdes:GetAttribute("occupied") == true then
randomdes = waitpoints[math.random(1, #waitpoints)]
else
NPC.Humanoid:MoveTo(waypoint.Position)
NPC.Humanoid.MoveToFinished:Wait()
end
end
I see that from the code.
What I mean is that you need to do SetAttribute("occupied", true) somewhere in the code to make randomdes:GetAttribute("occupied") read the value.
okay so like, most of the script works the only problem is when an npc is already in an occupied area it another npcs goes there, when it should be only one, ill put a picture here
the yellow spots are the areas the npcs path find to and when they reach that area, the occupied attribute becomes true, the npc is supposed to check if theres already someone there then dont go to that spot and if all spot occupied then dont spawn
Maybe you should just set the attribute to true when the npc finds the way point to move to because now it seems like another npc can go to the waypoint despite another npc already moving to it
for _, waypoint in pairs(path:GetWaypoints()) do
if randomdes:GetAttribute("occupied") == true then
randomdes = waitpoints[math.random(1, #waitpoints)]
else
randomdes:SetAttribute("occupied", true)
NPC.Humanoid:MoveTo(waypoint.Position)
NPC.Humanoid.MoveToFinished:Wait()
end
end
no thats not really the problem, even if the attribute is set to true the npcs still go to that area, and theres already a script that when the npc touches the waypoint it changes to occupied.
path:GetWaypoints returns a static list of positions, and it’s being calculated for the FIRST destination. when you change randomdes in the loop, it’s only updating the variable. it’s not updating the path object or the waypoints that the loop is iterating through.
Try something like this:
local pfs = game:GetService("PathfindingService")
local NPC = script.Parent
local debri = game:GetService("Debris")
local waitpoints = workspace:WaitForChild("Areas"):GetChildren()
-- wrapper function so we can run the code again easily
function MoveToRandomSpot()
local randomdes = waitpoints[math.random(1, #waitpoints)]
-- check if spot is taken before we even start
if randomdes:GetAttribute("occupied") == true then
task.wait(0.1)
return MoveToRandomSpot() -- stop this function here and try again
end
local path = pfs:CreatePath()
path:ComputeAsync(NPC.HumanoidRootPart.Position, randomdes.Position)
if path.Status == Enum.PathStatus.Success then
for _, waypoint in pairs(path:GetWaypoints()) do
-- check if spot got taken while we were walking
if randomdes:GetAttribute("occupied") == true then
return MoveToRandomSpot() -- stop walking the old path immediately and find a new spot
end
NPC.Humanoid:MoveTo(waypoint.Position)
NPC.Humanoid.MoveToFinished:Wait()
end
else
-- path failed (maybe blocked), try a different spot
return MoveToRandomSpot()
end
end
-- runs the function for the first time
MoveToRandomSpot()
I wrapped everything into a function, this lets us restart the logic whenever we want to (on pathing failed or occupied.)
When the script detects the spot is occupied, it calls MoveToRandomSpot again instantly, forcing the script to go back to the top, pick a new randomdes, and calculate a brand NEW path (your previous script only calculated the path once, for the first random dest it picked)
It’s not that :GetAttribute was failing, it was the fact that your previous code calculated the path for the first randomdes, iterated through the list and found an “unoccupied” spot, but would continue walking the OLD path