I’ve been trying for hours on an AI Pathfinder on how to detect if a player has moved too far from a waypoint or if player is too close to the npc, but I still haven’t found an optimized solution.
Currently, the code below just stutters for a split second.
Main Pathfinding
local function followPlayer(targetHRP)
while task.wait() do
local distanceToPlayer = (npc.HumanoidRootPart.Position - targetHRP.Position).Magnitude
if distanceToPlayer >= 18 then
local path = getPath(targetHRP.Position)
local waypoints = path:GetWaypoints()
for i, waypoint in pairs(waypoints) do
local distanceToWayPoint = (targetHRP.Position - waypoints[#waypoints].Position).Magnitude
if distanceToWayPoint > 18 then
break
end
if waypoint.Action == Enum.PathWaypointAction.Jump then
npc.Humanoid.Jump = true
end
npc.Humanoid:MoveTo(waypoint.Position)
npc.Humanoid.MoveToFinished:Wait()
end
else
hmd:MoveTo(targetHRP.Position)
end
end
end
local function pathFindTo(destination, player)
local target = findTarget(player)
if target and target.Humanoid.Health > 0 then
local targetHRP = target:WaitForChild("HumanoidRootPart")
coroutine.wrap(followPlayer(targetHRP))()
end
end
How the function is played
humanoid.Died:Connect(function()
check = false
end)
while task.wait() do
if (check) then
if character and character:FindFirstChild("HumanoidRootPart") then
local target = findTarget(player)
if target then
pathFindTo(target:WaitForChild("HumanoidRootPart").Position, player)
end
end
end
end
basically the solutions to the problems I want to find:
Detect if a player is too close to npc or too far from waypoint, then break the path (even if its on :Wait() ) and redo the findPath function.
and that’s all. If someone could help, I would be very glad as I am awake at 4 am agonizing what’s wrong.
local follow = true
local function followPlayer(targetHRP)
while task.wait() do
local distanceToPlayer = (npc.HumanoidRootPart.Position - targetHRP.Position).Magnitude
if distanceToPlayer >= 18 then
local path = getPath(targetHRP.Position)
local waypoints = path:GetWaypoints()
for i, waypoint in pairs(waypoints) do
local distanceToWayPoint = (targetHRP.Position - waypoints[#waypoints].Position).Magnitude
if distanceToWayPoint > 18 then
print("HI")
break
end
if waypoint.Action == Enum.PathWaypointAction.Jump then
npc.Humanoid.Jump = true
end
npc.Humanoid:MoveTo(waypoint.Position)
npc.Humanoid.MoveToFinished:Wait()
end
else
hmd:MoveTo(targetHRP.Position)
end
end
end
local function pathFindTo(destination, player)
local target = findTarget(player)
if target and target.Humanoid.Health > 0 then
local targetHRP = target:WaitForChild("HumanoidRootPart")
follow = false
task.wait()
follow = true
coroutine.wrap(function() followPlayer(targetHRP) end)()
end
end
this kind of works for detecting player movement while ignoring the wait function in the loop. But way too many threads open. Anyone know how to limit the amount of threads?
local maxThreads = 30
local activeThreads = 0
local isMoving = true
local lock = false
local ifPath = false
local secondLock = false
local waitForHumanoid = nil
local function followPlayer(targetHRP)
local distanceToPlayer = (npc.HumanoidRootPart.Position - targetHRP.Position).Magnitude
if distanceToPlayer >= 9 then
if (targetHRP.Position - vectorValue.Value).Magnitude > 7 and lock and not secondLock and ifPath then
ifPath = false
lock = false
secondLock = true
elseif lock == false then
activeThreads += 1
lock = true
local waypoints = {}
if ifPath == false then
ifPath = true
local path = getPath(targetHRP.Position)
waypoints = path:GetWaypoints()
end
for i, waypoint in pairs(waypoints) do
if activeThreads > 1 then
break
end
if waypoint.Action == Enum.PathWaypointAction.Jump then
npc.Humanoid.Jump = true
end
vectorValue.Value = waypoints[#waypoints].Position
secondValue = vectorValue.Value
npc.Humanoid:MoveTo(waypoint.Position)
npc.Humanoid.MoveToFinished:Wait()
if secondLock then
break
end
end
if secondLock then
secondLock = false
lock = true
end
activeThreads -= 1
end
else
isMoving = true
secondLock = true
while isMoving do
npc.Humanoid:MoveTo(targetHRP.Position)
task.wait()
if (npc.HumanoidRootPart.Position - targetHRP.Position).Magnitude > 9 then
isMoving = false
end
end
end
end
local function pathFindTo(destination, player)
local target = findTarget(player)
if target then
local targetHRP = target:WaitForChild("HumanoidRootPart")
while true and task.wait() do
if target.Humanoid.Health > 0 then
followPlayer(targetHRP)
end
end
end
print(target)
end
local function createThreads(target, player)
for i = 1, maxThreads do
coroutine.wrap(function() pathFindTo(target:WaitForChild("HumanoidRootPart").Position, player) end)()
task.wait(0.1)
end
end
Put another check within that for loop of the waypoints to check how far the player is from the NPC like you did with distancetowaypoint, if it’s too far then break.
Once it breaks out the for loop it’ll restart so that’s fine.