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
Try raycasting NPCs position to next point, if it finds anything on the ray, it means the npc will/is stuck somewhere