Pathfinding NPC is not acting as intended

Hello, i’ve been following this tutorial, i finished the script and noticed that the Pathfinding NPC acts weird while following the player, i have two problems:

  1. The Pathfinding NPC is choppy and doesn’t jump when there’s an obstacle in the way, instead it stops for about 5 - 10 seconds before doing anything. (However it’s able to detect the best way to find the player… unless it gets stuck, then it won’t react until the time given above).

  2. The Pathfinding NPC can’t outrun the player, no matter how much speed i give it.

These problems are just the opposite of what i intended to achieve, which was for the Pathfinding NPC to be quick and outrun the player, while constantly following them and not getting stuck.

Here’s the Pathfinding script:

local root = script.Parent.HumanoidRootPart
root:SetNetworkOwner(nil)
local zombie = script.Parent.Zombie

function findTarget()
	local dist = 200
	local target = nil
	for i, v in pairs(workspace:GetChildren()) do
		local hum = v:FindFirstChild("Humanoid")
		local humTarget = v:FindFirstChild("HumanoidRootPart")
		if hum and humTarget then
			if (humTarget.Position - root.Position).magnitude < dist and hum.Health > 0 then
				dist = (humTarget.Position - root.Position).magnitude
				target = humTarget
				if (root.Position - target.Position).magnitude < 6 then
					target.Parent.Humanoid:TakeDamage(20)
				end
			end
		end
	end
	return target
end

while wait() do
	local humTarget = findTarget()
	if humTarget then
		local ray = Ray.new(root.Position,(humTarget.Position - root.Position).Unit * 200)
		local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
		if hit then
			if hit:IsDescendantOf(humTarget.Parent) then
				zombie:MoveTo(humTarget.Position)
			else
				path = game:GetService("PathfindingService"):CreatePath()
				path:ComputeAsync(root.Position, humTarget.Position)
				points = path:GetWaypoints()
				if path.Status == Enum.PathStatus.Success then
				    for i, v in pairs(points) do
					    zombie:MoveTo(v.Position)
					    zombie.MoveToFinished:Wait()
					    if v.Action == Enum.PathWaypointAction.Jump then
						    zombie.Jump = true
					    end
					    if (points[#points].Position - humTarget.Position).magnitude > 15 then
						    break
					    end
				    end
				else
					zombie:MoveTo(humTarget.Position)
				end
			end	
		end
	end
end

One possible solution i tried was to replace every zombie:MoveTo(humTarget.Position) with zombie:MoveTo(humTarget.Position, humTarget) which actually kind of worked, it could outrun the player (Still couldn’t jump when needed) but i’m not sure if it’s actually not the way i’m intended to do it at all.

I also replaced wait(1) and wait(2) with wait() and it helped with the choppiness, however now the way to damage i added is way too fast and almost instantly kills the player.

Please tell me if this is the wrong category and if you didn’t understand something.

4 Likes

well you can change the NPCS walkspeed

My browser might be glitched, but it seems like

Hello, i’ve been following this tutorial

Doesn’t actually have a link for “this tutorial”.

Could you edit it in or post it in a reply? Thanks.

1 Like

i did, but same thing happens, it still can’t outrun, i’m guessing it is since pathfinding finds a position, so it’s constantly finding it and it’s the only way it can move towards the player.

Edited the post and it seems like the link works now, thanks for pointing that out. :slight_smile:

Change the zombies walkspeed in the script

1 Like

Changing the walkspeed of the Zombie on any way doesn’t work, it will reach the player faster, but it will have the same relative speed when it’s close.

1 Like

There is a solution to the choppy movement here.

So, the new MoveTo loop section would look like this:

for i, v in pairs(points) do
    zombie:MoveTo(v.Position)
    --zombie.MoveToFinished:Wait() --keep incase it's fixed in the future
    repeat
        distance = (v.Position - root.Position).magnitude
        wait()
    until
        distance <= 6
    if v.Action == Enum.PathWaypointAction.Jump then
        zombie.Jump = true
    end
    if (points[#points].Position - humTarget.Position).magnitude > 15 then
        break
    end
end

Now, the attacking part of the script can get complex. I think it should be a separate function that detects when the zombie’s body is touched, then it deals damage to the humanoid that touched it.

2 Likes

Tried that right now, seems to get stuck. :cry:

I solved the attack part adding a coroutine with a loop, the main problem i’m having right now is that the Zombie doesn’t jump when it’s needed to, and it seems like it’s zombie.MoveToFinished:Wait(), without it the Zombie can jump obstacles easily, however, when it’s time to find the player behind a wall and such it gets stuck, so removing it doesn’t seem viable, not sure what else i can do.

Have you tried setting the agent parameters when defining the pathfindingservice?

local pfs = game:GetService("PathfindingService"):CreatePath({AgentRadius = 3; AgentHeight = 5}

AgentRadius is basically the distance they path from walls.
AgentHeight is how tall the NPC is; any space under 5 studs tall won’t be calculated like underneath stairs.

I removed the “zombie:MoveToFinished:Wait()” line in my script.

You could also try to lower the distance before it recalculates the path.

if (points[#points].Position - humTarget.Position).magnitude > 10 then  --this
    break
end
2 Likes

Solved it, had to move path.Status == Enum.PathStatus.Success to another place, hope i don’t get any more problems with this.

for i, v in pairs(points) do
        if v.Action == Enum.PathWaypointAction.Walk then
		zombie:MoveTo(v.Position)
	else
		zombie.Jump = true
		zombie:MoveTo(v.Position)
	end
	if path.Status == Enum.PathStatus.Success then
		zombie.MoveToFinished:Wait()
	else
		zombie:MoveTo(plrTarget.Position)
	end
	if (points[#points].Position - plrTarget.Position).magnitude > 10 then
		break
       end
end

Thanks for your comments too, very appreciated :smile:

2 Likes

Cool beans man. :+1:

I hope they fine tune pathfinding in the future, it can get a bit confusing.

1 Like