I have this script the creates a path for NPCs in my game to use. But currently they will only generate the path once, so if let’s say there we’re to appear something infront of it, then the NPC will just keep walking into the wall.
Is there a way for the NPC to keep calculating the path?
This is the code I’m currently using
function MoveNPC(npcPart, npcPathFolder)
local waypoints = npcPathFolder:GetChildren()
local agentParams = nil
if Settings["TowerNPCNames"][npcPart.Name] then
agentParams = Settings["TowerAgentParams"]
else
agentParams = Settings["AgentParams"]
end
local currentWaypointIndex = 1
local currentWaypoint = waypoints[currentWaypointIndex]
local nextWayPointIndex
local reachedConnection
local blockedConnection
local currentWaypointIndex = 1
local Walkspeed = npcPart:GetAttribute("Walkspeed")
local animator = Instance.new("Animator", npcPart.Humanoid)
local idleAnimation = animator:LoadAnimation(ReplicatedStorage.Storage.Animations.Idle)
local runAnimation = nil
if Walkspeed < 16 then
runAnimation = animator:LoadAnimation(ReplicatedStorage.Storage.Animations.Walk)
elseif Walkspeed >= 16 then
runAnimation = animator:LoadAnimation(ReplicatedStorage.Storage.Animations.Run)
end
local idleAnimation2 = animator:LoadAnimation(ReplicatedStorage.Storage.Animations.Idle2)
idleAnimation.Priority = Enum.AnimationPriority.Idle
idleAnimation2.Priority = Enum.AnimationPriority.Idle
runAnimation.Priority = Enum.AnimationPriority.Movement
idleAnimation:Play()
local controller = npcPart:FindFirstChildOfClass("Humanoid")
local humanoid = npcPart:FindFirstChild("Humanoid")
humanoid.WalkSpeed = Walkspeed
for i, v in pairs(npcPart:GetDescendants()) do
if v:IsA("BasePart") then
v:SetNetworkOwner(nil)
end
end
local function getPath(destination)
local path = getPathCache(npcPart.PrimaryPart.Position, destination.Position, agentParams)
if npcPart ~= nil and npcPart:FindFirstChild("HumanoidRootPart") then
Paths[npcPart] = path
path:ComputeAsync(npcPart.PrimaryPart.Position, destination.Position)
end
return path
end
local function walkTo(destination)
local path = getPath(destination)
if path.Status == Enum.PathStatus.Success then
if Settings["VisualizePath"] then
if not workspace.VisualPoints:FindFirstChild(npcPart.Name) then
local folder = Instance.new("Folder")
folder.Name = npcPart.Name
folder.Parent = workspace.VisualPoints
else
workspace.VisualPoints:FindFirstChild(npcPart.Name):Destroy()
local folder = Instance.new("Folder")
folder.Name = npcPart.Name
folder.Parent = workspace.VisualPoints
end
local function getRandomNumber(minNumber, maxNumber)
return math.floor(math.random(minNumber, maxNumber))
end
if not PathColors[npcPart.Name] then
PathColors[npcPart.Name] = Color3.fromRGB(getRandomNumber(0, 255), getRandomNumber(0, 255), getRandomNumber(0, 255))
end
local pathColor = PathColors[npcPart.Name]
for index, waypoint in pairs(path:GetWaypoints()) do
local visualPart = Instance.new("Part")
visualPart.Anchored = true
visualPart.Size = Vector3.new(1,1,1)
visualPart.Color = pathColor
visualPart.CanCollide = false
visualPart.CanTouch = false
visualPart.Parent = workspace.VisualPoints:FindFirstChild(npcPart.Name)
visualPart.Position = waypoint.Position
end
end
for index, waypoint in pairs(path:GetWaypoints()) do
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
else
if npcPart ~= nil and npcPart:FindFirstChild("HumanoidRootPart") then
runAnimation:Play()
humanoid:MoveTo(destination.Position - (npcPart.HumanoidRootPart.CFrame.LookVector * -10))
task.wait(2)
runAnimation:Stop()
end
end
end
local function Patrol()
local currentWaypoint = waypoints[currentWaypointIndex]
if not npcPart:FindFirstChildOfClass("Humanoid") then return end
if not runAnimation.IsPlaying and npcPart.Humanoid.WalkSpeed > 0 then
runAnimation:Play(.1)
end
walkTo(currentWaypoint)
if currentWaypoint:FindFirstChild("WaitTime") then
idleAnimation:Stop(0.4)
local WaitTimeValue = currentWaypoint.WaitTime.Value
runAnimation:Stop(0.1)
idleAnimation2:Play()
task.wait(idleAnimation2.Length)
idleAnimation2:Stop(0.4)
idleAnimation:Play()
task.wait(WaitTimeValue - idleAnimation2.Length)
end
currentWaypointIndex = currentWaypointIndex + 1
if currentWaypointIndex > #waypoints then
currentWaypointIndex = 1
end
end
while task.wait() do
Patrol()
end
end