Pathfinding NPC is really slow (PLEASE HELP ME)

I need some help

(This might be kind of a long post so keep that in mind)

For 4 straight days I’ve been working on a Pathfinding NPC System, I’ve made improvements, but I couldn’t even get the main pathfinding system to work properly.

I don’t want to use pathfinding resource modules, because they aren’t as customizable as If I made my own. (I did try SimplePath)

(I’ve tried countless things, gotten help from DevForum posts, and youtube tutorials, but every single thing I tried had a flaw in it)

This is the main pathfinding script

function data:FollowPath(target:BasePart)

		task.spawn(function()
			Following = true

			-- Constant following
			while true do
				local initPos = target.Position
				print("got position!")

				-- If not closed then
				if Following == true then



					-- Compute the path
					data.Path:ComputeAsync(character.HumanoidRootPart.Position, target.Position)

					-- If the path was created successfuly
					if data.Path.Status == Enum.PathStatus.Success then
						local wps = data.Path:GetWaypoints()


						-- Incase the path was blocked
						data.Events.DefaultEvents.BlockedPath = data.Path.Blocked:Connect(function(blockedWPindex)

							if blockedWPindex >= NextWaypoint then

								data.Events.ManualEvents:End()

								data:FollowPath(target)
							end

						end)

						-- Visualize option
						if data.Settings.Visualize == true then

							task.spawn(function()
								if CurrentVisualizedWaypoints ~= nil then
									EF:ClearWaypoints(CurrentVisualizedWaypoints)
								end


								for i, waypoint in ipairs(wps) do
									local part = Instance.new("Part")
									part.Shape = Enum.PartType.Ball
									part.Color = Color3.new(0.682353, 1, 0.760784)

									-- Different actions
									if waypoint.Action == Enum.PathWaypointAction.Jump then
										part.Color = Color3.new(0.219608, 0.662745, 1)
									elseif waypoint.Action == Enum.PathWaypointAction.Custom then
										part.Color = Color3.new(1, 0.419608, 0.827451)
									end

									part.Material = Enum.Material.Neon
									part.CFrame = CFrame.new(waypoint.Position)
									part.Parent = workspace.Cache
									part.Name = i
									part.Anchored = true
									part.Size = Vector3.new(0.42,0.42,0.42)
									part.CanCollide = false

									table.insert(CurrentVisualizedWaypoints, part)


									task.delay(4, function()
										if part then
											part:Destroy()
										end
									end)
								end
							end)
						end


						-- // Move Behaviour
						for i, waypoint in pairs(wps) do
							-- If need to jump
							if waypoint.Action == Enum.PathWaypointAction.Jump then
								character.Humanoid.Jump = true
							end

							character.Humanoid:MoveTo(waypoint.Position)

							character.Humanoid.MoveToFinished:Wait()
							
						end

					else
						task.wait()
					end

				else
					break
				end


			end

		end)



	end

(It’s inside of a module)
(I’ve tried way too many things to list them all)

This current code of course has a flaw, the path updates too slowly, making the NPC easy to avoid

(I’ve seen people make the pathfinding NPC stop using pathfinding and just move to the target once it’s close, but I’d rather not do it that way.)

Is there any hope for me? please help I don’t want to give up :sob:

7 Likes

I guess whatever is calling the function has a pretty “long” wait, make the wait be way shorter

2 Likes

Have you tried using RunService instead of a while loop? Or use task.wait() instead of using Humanoid.MoveToFinished:Wait()

1 Like

using this line inside the for loop means that your script waits for the NPC to finish its current path before computing another, meaning its always gonna be “slow” because its finishing the current path before computing another. In a situation where the path is constantly changing, you dont want to use this.

Not waiting for the move to finish just makes the npc move towards the last waypoint

3 Likes

Connect a signal to reaching the next waypoint and then you can move to next point/recalculate path/or whatever you wanna do.

How do I calculate if the NPC has reached the next waypoint?

1 Like

You can just connection a function to humanoid.MoveToFinished, and then inside of that function handle moving onto the next waypoint step. You’ll still need to setup some sort of constant loop that recalculates the path though or your thing will always be slow to react

1 Like

You can try updating the NPC’s path more frequently. To cancel the current waypoint it is on you can just call :Move(Vector3.new(0, 0, 0) then run your updated waypoint with :MoveTo(). You could try running it, for example, every 0.25 seconds if it’s not too expensive.

1 Like

I don’t quite understand what you mean by this, could you elaborate a bit further?

I havent tried RunService on this project, but in my past project some years ago I did, and I had an issue since Heartbeat doesn’t yield the thread, it wouldnt wait before computing a new path, It’d just compute a new path every frame and walk to it, so the npc would just go crazy.

I tried what you said and, not looking too good, I havent found a way to update the path constantly

You can see the NPC kinda stutters (idk why) and yea it still thinks slowly since I couldn’t figure out how to

2 Likes

Have you set the NPC’s NetworkOwner of the PrimaryPart to nil? If no do that

-- idk put that somewhere
character.PrimaryPart:SetNetworkOwner(nil)
1 Like

Should the PrimaryPart be the head or the HumanoidRootPart?

1 Like

The HumanoidRootPart is the PrimaryPart

1 Like

Pretty sure I didn’t change anything

2 Likes

Then just do

character.HumanoidRootPart:SetNetworkOwner(nil)

(or do PrimaryPart, I am not really sure how NetworkOwner functions if the PrimaryPart is not the HRP)

2 Likes

Have you tried Magnitude? You might be able to incorporate it into your pathfinding and make the npc move a lot smoother. Here’s a good tutorial. Magnitude Tutorial

1 Like

@PENG_LINMEME
Man I love TheDevKing

But in what situation would I use magnitude? like what would I use it for exactly?

@yoshicoolTV
I changed the primary part to HRP, it does seem to move a little smoother but still updating slowly

2 Likes

For calculating the distance between things. In this case the distance between the npc and the player.

1 Like