New to pathfinding!

Hey guys! I’ve been trying to make a boss fight for the first time, but first and foremost, I want to get the boss moving properly.

Here is the code I have so far:

Code
local range  = 50

local PFS = game:GetService("PathfindingService")
local Humanoid = script.Parent:WaitForChild("Humanoid")
local HumanoidRootPart = script.Parent.HumanoidRootPart
local path = PFS:CreatePath()
local WalkAnim = Humanoid:LoadAnimation(script.Walk)
local BossMove1 = Humanoid:LoadAnimation(script.Move1)
local TweenService = game:GetService("TweenService")


local IsWalking = false


function GroundPound ()
	local AnimationPound = Humanoid:LoadAnimation(script.Move1)
	
	
end

function Playanim()

	BossMove1:Play()
	script.scream:Play()

end

BossMove1:GetMarkerReachedSignal("Pound"):Connect(function()

	print("Found the anim!")
	script.scream:Stop()
	local PoundRing = game.ServerStorage.BossStuff.Ring:Clone()
	PoundRing.CFrame = CFrame.new(script.Parent.RightHand.Position)
	PoundRing.Anchored = true
	PoundRing.Parent = workspace
	PoundRing.Touched:Connect(function(Part)
		if Part.Parent:FindFirstChild("Humanoid") and Part.Parent ~= script.Parent then
			Part.Parent:FindFirstChild("Humanoid"):TakeDamage(15)
		end
	end)
	local GroundPound = TweenService:Create(PoundRing,TweenInfo.new(3),{Size = Vector3.new(50,0.05,50); Transparency = 1})
	GroundPound:Play()
	script["Explosion or Crumble"]:Play()
	GroundPound.Completed:Wait()
	PoundRing:Destroy()
end)


while wait() do
	
	if IsWalking == true then

		if WalkAnim.IsPlaying == false then

			WalkAnim:Play()
		end
	elseif IsWalking == false then
		WalkAnim:Stop()
	end
	
	for i,Player in pairs(game.Players:GetPlayers()) do
		if (workspace:WaitForChild(Player.Name).HumanoidRootPart.Position - HumanoidRootPart.Position).Magnitude <= range then
			path:ComputeAsync(HumanoidRootPart.Position,Player.Character.HumanoidRootPart.Position)
			local waypoints = path:GetWaypoints()


			for i,waypoint in pairs (waypoints) do
				IsWalking = true
				print(path.Status)
				if waypoint.Action == Enum.PathWaypointAction.Jump then
					Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
				end
				Humanoid:MoveTo(waypoint.Position)
				
				--Humanoid.MoveToFinished:Wait(2)
				
 
			end

		end
	end
	
	
end

It works all fine and dandy, however, the movement is sometimes jagged and not straight. There is also an issue with the NPC encountering an obstacle, it wither doesn’t jjump at all, or jumps SEVERAL times making it fly up into the air.

I would also love to get some opinions on how to make it chase other people, this is the solution I came up with , but I’m guessing its poorly optimized having it consistently cyle through players and rerouting paths.

Thanks so much!

1 Like

Make sure you set networkownership to nil on the NPC at the start of the script. With regards to jumping, then you will need to set the Path Paramters, which include AgenHeight and AgentRadius.

You could use a touched function for the rootpart, if that’s touched then make the character jump. You also would just add a debounce so that they don’t consistently jump and it would look less choppy.

Also, the reason rootpart would be the best option is because anything below your root is less likely to get in the way of your path.

As for the jaggedness @BadDad2004 explained that part well. That’s just a problem related to the network trying to replicate the dummies movements from your side and the server. If you set the dummy to server aka ‘nil’, then the dummy will run with no jaggedness.

Would this be for the primarypart? I’ve never done this before, so it kinda piqued my interest.

I also added a part to each waypoint, its a mess since it continuously loops;
https://gyazo.com/d81cd98722b43307b42f4409192feb89

I need to find a way so that if theres a closer person, the path stops, otherwise it finds the route to the same player after it completes the path the first time

Is there any such thing as “Path.Completed:wait()” like tweening has?

Yes, PrimaryPart:
NPC.PrimaryPart:SetNetworkOwner(nil)
However, some people do it on every single part or mesh of an NPC:

for _, v in pairs(NPC:GetChildren()) do
	if v:IsA("MeshPart") or v:IsA("BasePart") and v:CanSetNetworkOwnership() then
		print("NetOwnership: ", v.Name)
		v:SetNetworkOwner(nil)
	end
end

I can’t say which way is correct/better. I tend to use full Humanoids for my NPC setups and have used both.

With regards to targeting, have a loop that controls what the NPC does:

  • scan for a target Player
  • if no target Player, find next Part in it’s path as target
  • Move to target

You are correct that there is an Event driven equivalent for MoveTo:

Humanoid:MoveTo(waypoint.Position)
Humanoid.MoveToFinished:Wait()

The MoveTo will wait until either the NPC reaches it’s destination or it will timeout after 8 seconds.

Don’t forget to set you Agent Parameters: PathfindingService:CreatePath

I used this example Roblox - Controlling Multiple AI with One Script (advanced) - Scripting Tutorial - YouTube as the basis of my current Pathfinding experiments.
Some people dismiss the built-in Pathfinding API as limited (which it is), but it can be bent to your will fairly easily as long as your environments are not too complex.

I’ll look more into this soon! Going to rewrite my code so its more optimized with the knowledge I’ve gotten, thanks!