How do i fix Pathfiding making movement glitchy? (npc after a little movement stays in one place to wait). AND i am NOT using “for” loop since i want NPC to have freshest path each tick. Because while NPC walking in one direction, player can move in another and get massive distance before NPC finishes walking through all waypoints and thinking of new path again
I’ve had a similar problem, I gave up but found SimplePath, it’s open-source and easier than doing it yourself.
Also I see some stuff that could be done better in your code, for example you’re computing the path twice in a row, once when you create it and right after creating it:
local path = CalculatePath() -- creates path and calculates path from creature to closest target
path:ComputeAsync(creaturePos, targetPos) -- immediately computes path again without even using previous one
Now that I read your code 30 more times to make this reply I think i see the problem you’re using only the second waypoint, is there any gameplay reason for it? If not you should iterate over all the waypoints, that way it should move smoothly.
If that doesn’t solve it then try creating the path object only once per creature (you’re creating a new path object every time you run CalculatePath()).
i assume you are trying to get the nearest player in the server so i made these scripts so take a look at them beacuse they work normally and doesnt make npc walk weird
modulescript:
local PathFindingManager = {}
local PathFindingService = game:GetService("PathfindingService")
function PathFindingManager.AdvancedPathFinding(root:Part, humanoid:Humanoid, target:Part)
local path = PathFindingService:CreatePath({
AgentCanJump = true,
AgentCanClimb = true
})
local success, errorMessage = pcall(function()
root:SetNetworkOwner(nil)
path:ComputeAsync(root.Position, target.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
for _,waypoint in ipairs(path:GetWaypoints()) do
humanoid:MoveTo(waypoint.Position)
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
humanoid.MoveToFinished:Wait()
end
else
warn("Path could not be computed due to uneven and complex terrain. Using MoveTo Instead.")
humanoid:MoveTo(target.Position)
end
end
return PathFindingManager
ServerScript (In ServerScriptService):
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local PathFindingManager = require(game.ServerScriptService.PathFindingManager)
local rig = workspace.Rig
local humanoid = rig.Humanoid
local primarypart = rig.PrimaryPart
local function GetNearestPlayer()
local closest = nil
local range = math.huge
for _,player in pairs(Players:GetPlayers()) do
local character = player.Character or player.CharacterAdded:Wait()
if character then
local distance = (primarypart.Position - character.PrimaryPart.Position).Magnitude
if distance < range then
range = distance
closest = character
end
end
end
return closest
end
RunService.PostSimulation:Connect(function()
local playerCharacter = GetNearestPlayer()
if playerCharacter then
PathFindingManager.AdvancedPathFinding(primarypart, humanoid, playerCharacter.PrimaryPart)
end
print("success")
end)
Replace wait(0) with task.wait() OR you could also use a stepped function (which is what I use for mine and might improve responsiveness a little). Anyways, in if #waypoints > 1 then change the operator to if #waypoints >= 1 then as its entirely possible that the waypoints table only has a single waypoint at a given moment.
He wants the Humanoid to always move to the second waypoint since the first waypoint is at the position of the start of the path, so #waypoints > 1 makes sense because moving to the first waypoint will do nothing.
You could have the path calculation run in parallel to the script that actually moves the Humanoid. This way there will be one thread that constantly updates the NPC path and the other thread will move the Humanoid to the new location whenever it finished its last moving operation