Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How could i detect if a NPC gets stuck with PathFindingService?

Hello, everyone!

I am having a problem with the service: PathFindingService.

The thing is that i do not know how i could detect once a NPC gets stuck once following waypoints of the path. Like for example, i have a door that can open and close once i press a certain keybind, but you close the door on the NPC that is currently trying to follow the waypoints to go through the door, and now it it stuck against the door. But how would the NPC know if he is stuck, how would i know, either?

Anyways, here is my code, (The AI Script inside of the NPC):

--Variables
local human = script.Parent.Humanoid
local root = script.Parent.HumanoidRootPart
local pathfindService = game:GetService("PathfindingService")

local clone = script.Parent:Clone()

script.Parent.PrimaryPart:SetNetworkOwner(nil)

--Functions

function findTarget()
local target = nil
local dist = 100000
	
for _,v in pairs(game.Workspace:GetChildren()) do
	if v.Name ~= script.Parent.Name and v.Name ~= "Ninja" then
		local plrRoot = v:FindFirstChild("HumanoidRootPart")
		
		if plrRoot ~= nil then
			if (root.Position - plrRoot.Position).Magnitude < dist and plrRoot.Parent.Humanoid.Health > 0 then
				target = plrRoot
				dist = (root.Position - plrRoot.Position).Magnitude
				
				return target
			end
		else
			return nil
		end
	end
	end
end

function unstuck()
	local xrand = math.random(-1,1)
	local zrand = math.random(-1,1)
	human:MoveTo(Vector3.new(xrand,0,zrand))
	human.Jump = true
	wait(0.3)
end

function wander()
	human.WalkSpeed = 10
	local xrand = math.random(-100,100)
	local zrand = math.random(-100,100)
	local spot = Vector3.new(xrand,0,zrand)
	local path = pathfindService:CreatePath()
	path:ComputeAsync(root.Position,root.Position + spot)
	local waypoints = path:GetWaypoints()
	if path.Status == Enum.PathStatus.Success then
		for _,v in pairs(waypoints) do
			if findTarget() ~= nil then
				break
			end
			if v.Action == Enum.PathWaypointAction.Jump then
				human.Jump = true
			end
			human:MoveTo(v.Position)
			human.MoveToFinished:Wait()
		end
	elseif path.Status == Enum.PathStatus.NoPath then
		print("Failed wandering path.")
	end
end

function attack(target)
	if (root.Position - target.Position).Magnitude < 2.5 then
		local humanoid = target.Parent:FindFirstChild("Humanoid")
		if humanoid.Health > 0 then
			humanoid:TakeDamage(10.5)
		end
	end
end

function checkSight(target)
	local ray = Ray.new(root.Position,(target.Position - root.Position).Unit*150)
	local hit,pos = game.Workspace:FindPartOnRayWithIgnoreList(ray,{script.Parent;})
	
	if hit then
		if hit:IsDescendantOf(target.Parent) then
			return true
		else
			return false
		end
	end
end

function findPath(target)
	local path = pathfindService:CreatePath()
	path:ComputeAsync(root.Position,target.Position)
	
	if path.Status == Enum.PathStatus.Success then
		return path
	else
		print("Can't find the path to target, generating a new...")
		return nil
	end
end

function died()
	script.Parent:BreakJoints()
	wait(5)
	script.Parent:Destroy()
	clone.Parent = game.Workspace
end

function main()
	local target = findTarget()
	
	if target ~= nil then	
		human.WalkSpeed = 14.5	
		if checkSight(target) then
			human:MoveTo(target.Position)
			attack(target)
		else
			human:MoveTo(target.Position)
			local path = findPath(target)
			
			if path ~= nil then
				local waypoints = path:GetWaypoints()
				print(#waypoints)
				
				for _,v in pairs(waypoints) do
					if v.Action == Enum.PathWaypointAction.Jump then
						human.Jump = true
					end
					human:MoveTo(v.Position)
					human.MoveToFinished:Wait(2)
				end
			end
		end
	else
		wander()
	end
end

human.Died:Connect(died)

--while loop
while wait(0.1) do
	main()
end

Where would i detect when i need to call the unstuck() function, how do i detect when the NPC is stuck?

Any help is appreciated here.

Thanks,

Dexiber.

1 comment

1

Try raycasting NPCs position to next point, if it finds anything on the ray, it means the npc will/is stuck somewhere

1 answer

✓ Accepted answer

Do a simple magnitude check, to see whether npc is moving.

local npcIsStuck = false
local lastPosition
spawn(function()
	while root.Parent do
		lastPosition = root.Position
		wait(1) -- check interval
		if (lastPosition - root.Position).magnitude < 1 then
			npcIsStuck = true
		else
			npcIsStuck = false
		end
	end
end)

Hope this helps!

2 comments

0

this is what i was gonna try out, but i don't really know where to put it.

0

Well, it worked thanks!

This discussion is preserved as it was. New answers, comments, and votes are closed.