Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How to stop stuttering in a pathfinding follow NPC?

Trying to make an NPC that uses pathfinding to follow a player, but whenever I test it the NPC stutters and lacks behind. Any help?

local workspace = game.Workspace



function moveToPostition(moveTo)
    local path =  game:GetService("PathfindingService"):ComputeRawPathAsync(script.Parent.Parent.LowerTorso.Position, moveTo, 200)
    local points = path:GetPointCoordinates()

    for p = 1, #points do
        script.Parent:MoveTo(points[p])
        repeat wait() until script.Parent.MoveToFinished
    end
end

while true do
	wait(0.01)
	walkevent = moveToPostition(workspace.BoxedHouses.Torso.Position)       
end

11 comments

0

MoveToFinished is not a boolean, it's an event.

0

Well I don't know how to make it wait for an event so can you be a bit more descriptive?

0

1/2 To work off of what incapaz mentioned, you can use script.Parent.MoveToFinished:Wait() to yield properly. Not sure if that will necessarily solve your problem, though. Roblox's pathfinding yields a ton of unnecessary points (as do most pathfinding algorithms). My solution to the unnatural stuttery movement was simply raycast between each brick to gauge visibility, and then deleting extraneous

0

2/2 bricks. Of course, this comes with a performance cost, but I've found that it's pretty worth it for the fluid movement.

0

Also, as a note, you can't yield for 1/100th of a second, so your wait(0.01) is probably just better placed being written as wait(); :P Doesn't make a difference functionally, but the number is misleading.

0

Using script.Parent.MoveToFinished:Wait() made it stutter less, but it waits any time I turn.

0

I don't understand what you mean by raycasting in-between bricks. There are no bricks.

0

My problem is, instead of chasing me (always taking the shortest and fastest route) it more of just mirrors the moves I made half a second ago.

0

My mistake, 'bricks' was the wrong convention to use there, you have them denoted as points. Same concept; you can simply raycast between each of those 'points' and ensure that there is nothing in the way. That would just fix unnatural movement upon further reflection though, I'm not really sure why you're yielding at each turn. Does it wait long?

0

I just read your latest comment, it's probably just an issue that you aren't pathfinding often enough. See, you're just following the path until you've reached the last point, rather than actually checking for the player every so often.

0

Problem is, I want things to be in the way. Also its just a stutter when it stops.

1 answer

Alright, not sure if I'm still misunderstanding the problem somewhat, but let me know if the following works:

local pathfindingCoolDown = 0.2;

function moveToPosition(moveTo)
    local path =  game:GetService("PathfindingService"):ComputeRawPathAsync(script.Parent.Parent.LowerTorso.Position, moveTo, 200)
    local points = path:GetPointCoordinates()
	
	local startTime = tick();
    for p = 1, #points do
        script.Parent:MoveTo(points[p])
        script.Parent.MoveToFinished:Wait();
		if(startTime-tick() > pathfindingCoolDown) then
			return
		end
    end
end

while wait() do
    moveToPosition(workspace.BoxedHouses.Torso.Position)       
end

2 comments

0

That made it slower.

0

Try replacing the while wait() do with a while true do. Seems to make it stutter free for me. Just accommodate it with some error checking to be sure that it doesn't run unyieldingly while paths aren't being generated.

This discussion is preserved as it was. New answers, comments, and votes are closed.