NPC Pathfinding not creating jump waypoints

Hey, so I am trying to make an npc that simply follows the player. The problem I’m having though is that when the npc runs into a wall, it absolutely refuses to jump over it. If I make it a really short wall it jjust runs into the wall and keeps trying to push through it, when I make it a taller wall the npc literally just walks around, even though the wall is still short enough for it to jump over. I’ve tried several things, but it just will not jump and I have no idea why! Below is a video of what’s happening, as well as my script, if anyone knows what’s wrong I’d really appreciate the help.

Link because video file was “Too large”

wait(3)
local pathfindingService = game:GetService("PathfindingService")
local fightingNpcs = workspace:WaitForChild("Map"):WaitForChild("FightingNPCs")
local RunS = game:GetService("RunService")

local function handleNpc(npc)
	if npc ~= nil then
		if npc:FindFirstChild("HumanoidRootPart") ~= nil then
			local waypoints = nil

			local function MoveTONextWaypoint()
				local waypoint = waypoints[2]
				if waypoint == nil then
					print(waypoints)
					--[[runAnimation:Stop()]] 
					return 
				else
					if waypoint.Action == Enum.PathWaypointAction.Jump then
						print("IT SHOULD BE JUMPING")
						npc.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
					else
						print(waypoint.Action)
					end
					npc.Humanoid:MoveTo(waypoint.Position)
					
				end
			end
			
			npc.Humanoid.MoveToFinished:Connect(function(reached)
				if reached == false then print("Has not reached")--[[npc:SetPrimaryPartCFrame(CFrame.new(waypoints[waypointIndex].Position))]] return end
				MoveTONextWaypoint()
			end)

			npc.AttributeChanged:Connect(function(attribute)
				--if attribute == "Destination" then
				if npc:GetAttribute("Target") ~= nil then
					local targetChar = workspace:FindFirstChild(npc:GetAttribute("Target"))
					if targetChar ~= nil then
						local targetHrp = targetChar:FindFirstChild("HumanoidRootPart")
						--local destination = npc:GetAttribute("Destination")
						if targetHrp ~= nil then
							local destination = targetHrp.Position
							if (workspace.CurrentCamera.Focus.Position - destination).Magnitude > 500 then
								--npc.Parent = game.ReplicatedStorage
								--npc:SetPrimaryPartCFrame(CFrame.new(destination))
							else
								--npc.Parent = npc
								local path = pathfindingService:CreatePath({
									["AgentRadius"] = 3,
									["AgentHeight"] = 5,
									["AgentCanJump"] = true,
									["WaypointSpacing"] = 4,
									["Costs"] = {
										["Water"] = 20
									}
								})
								local success, returned = pcall(path.ComputeAsync, path, npc.HumanoidRootPart.Position, destination)
								if success == true and path.Status == Enum.PathStatus.Success then
									--print("Computed new path")
									--print(destination)

									--print(path.Instance)
									--runAnimation:Play()
									waypoints = path:GetWaypoints()
									MoveTONextWaypoint()
									--print("Npc should be moving")
								else
									print("Path failed")
									print(success)
									print(path.Status)
									path:ComputeAsync(npc:FindFirstChild("HumanoidRootPart").Position, destination)
									--npc:SetPrimaryPartCFrame(CFrame.new(destination))
								end
							end
						else
							print("Target hrp is nil")
						end
					end
				else
					
				end
			end)
		end
	end
end

local connection = nil
for i, folder in ipairs(fightingNpcs:GetChildren()) do
	if folder.Name == "TestFolder" then
		for i, npc in ipairs(folder:GetChildren()) do
			handleNpc(npc)
		end
	elseif folder.Name == "Platforms" then
		local allPlatforms = folder:GetChildren()
		for i, platform in ipairs(allPlatforms) do
			for i, spawnBlock in ipairs(platform:GetChildren()) do
				if spawnBlock.Name == "SpawnBlock" then
					if #(spawnBlock:GetChildren()) > 0 then
						for i, npc in ipairs(spawnBlock:GetChildren()) do
							handleNpc(npc)
						end
					end
				end
			end
		end
	else
		print(folder.Name)
		print("IS THE FOLDER")
		for i, spawnBlock in ipairs(folder:GetChildren()) do
			if #(spawnBlock:GetChildren()) > 0 then
				print(#(spawnBlock:GetChildren()))
				for i, npc in ipairs(spawnBlock:GetChildren()) do
					handleNpc(npc)
				end
			end
		end
	end
end

Is the code printing “it should be jumping”? And is the npc’s jump power higher than 0?

Nope, it’s not printing at all. It’s jump power is 50, and I’ve even tried using jumpheight instead to see if that would change anything. Both gave the same result. In the video, you’ll see that the waypoints are red when going from one side of the wall to the other, what does that mean? I assumed it meant it was blocked but not even connecting a blocked event has worked.

Its because you set the npc “CanJump” to true but you didnt add jump when it jumps.
Also there is documentation on roblox for pathfinding

I am confused as to what you mean, I do tell it to jump if the waypoint action is jump right here:

if waypoint.Action == Enum.PathWaypointAction.Jump then
	print("IT SHOULD BE JUMPING")
	npc.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
else
	print(waypoint.Action)
end

It’s even supposed to print that the npc should be jumping, the waypoint action is simply never jump and it’s always walk. So I’m not entirely sure what you mean, if you could elaborate that would be nice. And I’ve read the documentation.

Your script is very unoptimized that might cause inner calculation overload and cause the pathfidning AI to not generate right, You should follow the pathfinding guide in roblox official tutorial page.

Pathfiding itseld shouldnt be more that 20 lines of code

Pathfinding although simple isnt all thats going on there from what I read.

Also for OP , The code looks fine at least to me, but that pcall looks a bit strange to me. i do beleive path.ComputeAsync is meant to be path:ComputeAsync(StartPosition, EndPosition). Maybe that could be your issue?

I have never seen it done the way you did it here.

I mean if you disregard the print statements and comments then everything that utilizes pathfinding is in fact, pretty much only 20 lines of code. The other stuff you see is more-so set-up for other functionalities. I do believe that there is some optimization issues going on though, because I recently discovered that my waypoints were, I guess I should say “un-aligned” (If that’s even a word). Like, the npc was “reading” a waypoint that it should not have been currently reading, if that makes sense at all (And sorry if it doesn’t). That being said, I decided to change the MoveTONextWaypoint() function and had it check the waypoints and change them accordingly:

local function MoveTONextWaypoint()
				waypointIndex += 1
				if waypoints[waypointIndex] ~= nil then
					local waypoint = waypoints[waypointIndex]
					if waypoint == nil then
						waypoint = waypoints[waypointIndex - 1]
					end
					if waypoint.Position == lastPosition then
						waypoint = waypoints[waypointIndex + 1]
					end
					if waypoint == nil then
						return 
					else
						if waypoint.Action == Enum.PathWaypointAction.Jump then
							npc.Humanoid.Jump = true
						else
						end
						npc.Humanoid:MoveTo(waypoint.Position)
						lastPosition = waypoint.Position
						npc.Humanoid.MoveToFinished:Wait()
					end
				end
			end

And I modified the rest of my script to:

npc.Humanoid.MoveToFinished:Connect(function(reached)
				if reached == false then print("Has not reached") return end
				MoveTONextWaypoint()
			end)

			npc.AttributeChanged:Connect(function(attribute)
				if npc:GetAttribute("Target") ~= nil then
					local targetChar = workspace:FindFirstChild(npc:GetAttribute("Target"))
					if targetChar ~= nil then
						local targetHrp = targetChar:FindFirstChild("HumanoidRootPart")
						if targetHrp ~= nil then
							local destination = targetHrp.CFrame.Position + Vector3.new(0, 0, -1)
							if (workspace.CurrentCamera.Focus.Position - destination).Magnitude > 500 then
							else
								local path = pathfindingService:CreatePath({
									["AgentRadius"] = 3,
									["AgentHeight"] = 5,
									["AgentCanJump"] = true,
									["WaypointSpacing"] = 4
								})
								local success, returned = pcall(path.ComputeAsync, path, npc.HumanoidRootPart.Position, destination)
								if success == true and path.Status == Enum.PathStatus.Success then
									waypoints = path:GetWaypoints()
									if waypoints ~= nil then
										waypointIndex = 1
										MoveTONextWaypoint()
									end
								else
									print("Path failed")
									print(success)
									print(path.Status)
									path:ComputeAsync(npc:FindFirstChild("HumanoidRootPart").Position, destination)
								end
							end
						else
							print("Target hrp is nil")
						end
					end
				else
					
				end
			end)

It now jumps over the shorter wall, but it still chooses to walk around the taller wall instead, which is rather interesting to me. I believe it has something to do with the pcall as @09glich2 mentioned, though I’m also going to try to follow the documentation’s style a little more as well. I hadn’t done so because directly following it was not working for what I need the npc to do, I’ve been trying to implement it as best as I could.

Just attempted to do without the pcall, and I received the same results. Though in the process, I tried standing on the wall, and discovered that the path is not being created when the player character is at a position of higher elevation. And when approaching the player FROM a higher elevation, it jumps in the same spot several times before finally coming down. Do you guys know what might be the reason for this?