Hello Roblox Developers,
I hope you’re all doing well. I am currently working on a project involving NPC pathfinding in Roblox, and I’ve encountered a challenge that I could use some help with.
I am facing difficulties with dynamically updating the pathfinding for an NPC as the player moves. The current implementation only recalculates the path when the NPC reaches its destination, resulting in a large delay before the NPC starts pathfinding to the player’s updated position.
Short video of the problem:
Here is all of my code, just one script! You can place it inside of a normal rig to test it.
local players = game:GetService("Players")
local npc = script.Parent
local Humanoid = npc:WaitForChild("Humanoid")
local npcHumanoidRootPart = npc:WaitForChild("HumanoidRootPart")
local PathfindingService = game:GetService("PathfindingService")
npcHumanoidRootPart:SetNetworkOwner(nil)
local nearestPlayer = nil
local minDistance = nil
local pathfinderPosition = nil
local path = nil
local goal = nil
local target = nil
local waypoints = nil
local folder = nil
local targetPosition = nil
local visualize = true
if visualize then
folder = Instance.new("Folder")
folder.Name = "Waypoints"
folder.Parent = workspace
end
local function FindNearestPlayer()
nearestPlayer = nil
minDistance = math.huge
pathfinderPosition = npcHumanoidRootPart.Position
for _, player in ipairs(players:GetPlayers()) do
local character = player.Character
if character and character:FindFirstChildOfClass("Humanoid") and character:FindFirstChildOfClass("Humanoid").Health > 0 then
local distance = (character.HumanoidRootPart.Position - pathfinderPosition).magnitude
if distance < minDistance then
nearestPlayer = player
minDistance = distance
end
end
end
return nearestPlayer
end
local function getPath(destination)
local path = PathfindingService:CreatePath()
path:ComputeAsync(npc.HumanoidRootPart.Position, destination)
return path
end
local function visualizeWaypoints(waypoints)
for i, child in ipairs(folder:GetChildren()) do
child:Destroy()
end
for i, waypoint in ipairs(waypoints) do
local part = Instance.new("Part")
part.Shape = Enum.PartType.Ball
part.Color = Color3.fromRGB(98, 87, 255)
part.Material = Enum.Material.Neon
part.CFrame = CFrame.new(waypoint.Position)
part.Name = i
part.Anchored = true
part.Size = Vector3.new(1, 1, 1)
part.CanCollide = false
part.Parent = folder
end
end
local function pathFindTo(destination, goal)
if destination ~= targetPosition then
targetPosition = destination
target = goal.Character
if waypoints then
table.clear(waypoints)
end
if target and target.Humanoid.Health > 0 then
path = getPath(destination)
waypoints = path:GetWaypoints()
if folder then
visualizeWaypoints(waypoints)
end
for i, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
Humanoid:MoveTo(waypoint.Position)
Humanoid.MoveToFinished:Wait()
end
end
end
task.wait()
end
while true do
goal = FindNearestPlayer()
if goal then
pathFindTo(goal.Character.HumanoidRootPart.Position, goal)
else
task.wait(1)
end
end
I am seeking guidance on how to implement a dynamic pathfinding system that updates in real-time as the player moves. The NPC should continuously recalculate its path every time the function is called. The real reason this happens is because of Humanoid.MoveToFinished:Wait()
, but I can’t remove that without breaking the pathfinding system.
Thank you to anyone who can help.
p.s. please don’t tell me to use SimplePath or Forbidden API, they both have issues which is why im making a custom pathfinding system.
issues
SimplePath issue: does weird manuvers around corners and shakes a bunch, ONLY when constantly updating path (which i need to do). Forbidden API issue: pathfinder sometimes just starts pathing super slowly and freezes until the player starts moving.