Pathfinding script's path object returning Enum.PathStatus.NoPath

I’m working on a pathfinding script, and it’s been working for the most part, apart from a specific location in my game’s map, the construction site. I’ve done some basic print debugging, and I’ve found that the script is getting stuck in a loop, because if the path is not successful, the script will re-run the function. Through printing, I’ve also found that the path status is Enum.PathStatus.NoPath for a very strange reason. I tried looking on the developer hub for more information as to what causes this and what it means, but learnt nothing about it. Here’s the code

local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local lowerTorso = script.Parent:WaitForChild("LowerTorso")

local grab = script.Parent:WaitForChild("Grab")
local grabAnim = myHuman:LoadAnimation(grab)
grabAnim.Priority = Enum.AnimationPriority.Action
local area = script.Parent:WaitForChild("Zone").Value
local lastHealth = myHuman.Health
local lastAttack = tick()
local attackTime = 0.9
local attackDamage = 5
local angry = false

local function yieldTillDamaged()
	if myHuman.Health < lastHealth and angry == false then
		lastHealth = myHuman.Health
		
		local newCoroutine = coroutine.create(function()
			angry = true
			wait(25)
			angry = false
		end)
		
		coroutine.resume(newCoroutine)
	end
end

myHuman.HealthChanged:Connect(yieldTillDamaged)

local grabSound = head:WaitForChild("Attack")

function walkRandomly()
	local xRand = math.random(-40, 40)
	local zRand = math.random(-40, 40)
	
	local goal = area.Position + Vector3.new(xRand,0,zRand)
	
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position, goal)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			
			print("Moving to waypoint!")
			myHuman:MoveTo(waypoint.Position)
			local timeOut = myHuman.MoveToFinished:Wait(3)
			if not timeOut then
				myHuman.Jump = true
				walkRandomly()
			end
		end
	else
		wait(1)
		print("Path was not a success, restarting process")
		walkRandomly()
	end
end

function findPath(target)
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position,target.Position)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success and angry == true then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			myHuman:MoveTo(waypoint.Position)
			
			local timeOut = myHuman.MoveToFinished:Wait(3)
			
			if not timeOut then
				myHuman.Jump = true
				findPath(target)
				break
			end
			
			if checkSight(target) then
				repeat
					myHuman:MoveTo(target.Position)
					attack(target)
					wait(0.1)
					if target == nil then
						break
					elseif target.Parent == nil then
						break
					end
				until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
				break
			end
			if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
				findPath(target)
				break
			end
		end
	end
end

function checkSight(target)
	local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
	local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
	if hit then
		if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
			return true
		end
	end
	return false
end

function findTarget()
	local dist = 100
	local target = nil
	local potentialTargets = {}
	local seeTargets = {}
	
	for i, v in ipairs(workspace:GetChildren()) do
		local inMissionBool = v:FindFirstChild("IsInMission")
		local missionZoneValue = v:FindFirstChild("MissionZone")
		
		local canContinue = false
		
		if inMissionBool and missionZoneValue then
			if inMissionBool.Value == true and missionZoneValue.Value == script.Parent.Zone.Value then
				canContinue = true
			end
		end
		
		if canContinue == true then
			local human = v:FindFirstChild("Humanoid")
			local torso = v:FindFirstChild("HumanoidRootPart")
			if human and torso and v.Name ~= script.Parent.Name then
				if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 then
					table.insert(potentialTargets,torso)
				end
			end
		end
	end
	
	if #potentialTargets > 0 then
		for i,v in ipairs(potentialTargets) do
			if checkSight(v) then
				table.insert(seeTargets, v)
			elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
				target = v
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	
	if #seeTargets > 0 then
		dist = 200
		for i,v in ipairs(seeTargets) do
			if (myRoot.Position - v.Position).magnitude < dist then
				target = v
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	
	return target
end

function attack(target)
	if (myRoot.Position - target.Position).magnitude < 5 and tick() > lastAttack + attackTime then
		lastAttack = tick()
		grabAnim:Play()
		grabSound:Play()
		if target.Parent ~= nil then
			target.Parent.Humanoid:TakeDamage(attackDamage)
		end
	end
end

function died()
	wait(5)
	game:GetService("Debris"):AddItem(script.Parent,0.1)
end

myHuman.Died:Connect(died)

function main()
	local target = findTarget()
	print("In main!")
	
	if target then
		myHuman.WalkSpeed = 13
		print("Target found!")
		findPath(target)
	else
		print("Target not found, walking randomly")
		myHuman.WalkSpeed = 8
		walkRandomly()
	end
end

while wait(0.1) do
	if myHuman.Health <= 0 then
		break
	end
	
	main()
end

Keep in mind, this only fails with characters inside of the construction site in my game, but works everywhere else, despite all of them having the same scripts (I use commands to make sure they do).

If you could tell me why the path is behaving like this, I’d appreciate that. Here’s a video of the NPCs normally:

At the construction site, they stay completely still.

2 Likes

If it works everywhere else, it must be that there is no path for them to follow through it. Do you have any weird meshes/hitboxes possibly blocking the path?

You should take the scripts to a new game and make a progressively harder jumping course, with bigger gaps and smaller and smaller platforms. If they can do the entire thing, then there is something wrong with your script. If they eventually stop and return a NoPath, there must be a jump or scene like that in your site which they cannot process.

I will look over your script again once I finish eating.

I’m not sure, let me check (30 chars)

No, I ran a test and checked from the server, there aren’t any parts obstructing the path, I’ll try moving the NPCs and see how that works

Nope, it didn’t work, let me see if the NPCs need to be more spaced out to work

Your code seems to work fine. Have you tried your pathfinding through an obby? Does the construction site have an area zone?

No, I hovered my mouse over the area, from the server in the game, and there was no area zone.

I do have a helpful observation, however. When I was trying to see if it was because the NPCs were too close, I used another mission zone’s thugs, and they were trying to move to their zone (Inside all of the NPCs, there is an ObjectValue called “Zone”, and the value is a part in ReplicatedStorage, their zone. They get the position of it, and add a random value of -20 up to 20 to the X value of the position, and they do the same for the Z value. When I tested, I realized they were walking towards their old zone, and strangely, they were actually successfully able to navigate through the city to their zone, which means that there’s something about moving to the construction site zone position that makes it unable to move there, every single time you try to randomly generate a path. I do have to say, the zone part for the construction site is much larger than all of the other zones, so I will try to scale it down and see what happens when I do that.

Meaning, it’s not something close in the surroundings of the NPCs blocking the path (They were able to navigate out), it’s something near the zone position.

Weirdly, this is the middle position of the zone.

HOLD ON, It might be because the zone is too tall! I’ll add a part in my script that makes the humanoidrootpart’s y position the y value of the MoveTo Vector3, and x and z values to be that of the zone’s part.

Edit: THIS FIXED IT!

7 Likes

YESS! I FIXED IT! FINALLY!
Thanks a ton for your time, I’m so happy right now!

1 Like

Nice! Yeah, unfortunately the pathfinding calculates a path and instead of making the waypoints to the last area where the humanoid could walk, it just gives up. Glad you fixed it, good luck on your game!

1 Like

Thanks, you too.⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Thank you for explaining how you solved it. :pray:

3 Likes