and whenever I get near the NPC, it slightly tiptoes to me and stops
Error:
Workspace.Dummy.Script:37: attempt to index nil with ‘Position’
local pfs = game:GetService("PathfindingService")
local wps = {}
local path = pfs:CreatePath()
local wpIdx = 1
local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
local humrp = char.HumanoidRootPart
local function findTarget()
local players = game.Players:GetPlayers()
local MaxDistance = 9999999999
local nearestTarget
for i,v in pairs(players) do
if (v.Character) then
local target = v.Character
local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude
if (distance < MaxDistance) then
nearestTarget = target
MaxDistance = distance
end
end
end
return nearestTarget
end
local function followPath(goal)
path:ComputeAsync(hrp.Position, goal.Position)
wps = {}
if path.Status == Enum.PathStatus.Success then
wps = path:GetWaypoints()
wpIdx = 1
hum:MoveTo(wps[wpIdx].Position)
end
end
hum.MoveToFinished:Connect(function(reached)
if reached and wpIdx < #wps then
wpIdx += 1
if wps[wpIdx].Action == Enum.PathWaypointAction.Jump then
hum.Jump = true
end
hum:MoveTo(wps[wpIdx].Position)
end
end)
path.Blocked:Connect(function(blockedWpIDX)
if blockedWpIDX > wpIdx then
local target = findTarget(script.Parent.HumanoidRootPart)
if target ~= nil then
followPath(target.Torso, target)
end
end
end)
game:GetService("RunService").Heartbeat:Connect(function(deltatime)
local target = findTarget(script.Parent.HumanoidRootPart)
if target ~= nil then
followPath(target.Torso, target)
end
end)
Set AgentCanClimb to true in your agent parameters then and don’t change the cost since PathfindingLinks automatically have a cost of 1.
Code:
local pfs = game:GetService("PathfindingService")
local wps = {}
local path = pfs:CreatePath({
AgentCanClimb = true,
})
local wpIdx = 1
local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
local humrp = char.HumanoidRootPart
local function findTarget()
local players = game.Players:GetPlayers()
local MaxDistance = math.huge
local nearestTarget = nil
for i,v in players do
if (v.Character) then
local target = v.Character
local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude
if (distance < MaxDistance) then
nearestTarget = target
MaxDistance = distance
end
end
end
return nearestTarget
end
local function followPath(goal)
path:ComputeAsync(hrp.Position, goal.Position)
table.clear(wps)
if path.Status == Enum.PathStatus.Success then
wps = path:GetWaypoints()
wpIdx = 1
hum:MoveTo(wps[wpIdx].Position)
end
end
hum.MoveToFinished:Connect(function(reached)
if reached and wpIdx < #wps then
wpIdx += 1
if wps[wpIdx].Action == Enum.PathWaypointAction.Jump then
hum.Jump = true
end
hum:MoveTo(wps[wpIdx].Position)
end
end)
path.Blocked:Connect(function(blockedWpIDX)
if blockedWpIDX > wpIdx then
local target = findTarget(script.Parent.HumanoidRootPart)
if target then
followPath(target.Torso, target)
end
end
end)
game:GetService("RunService").Heartbeat:Connect(function(deltatime)
local target = findTarget(script.Parent.HumanoidRootPart)
if target then
followPath(target.Torso, target)
end
end)
Fixed it!
I think it was because the function wasn’t waiting for it to be done moving.
I had to do task.wait, because hum.MoveToFinished:Wait() wouldn’t work for some reason.
It still twitches a little bit though.
local pfs = game:GetService("PathfindingService")
local wps = {}
local path = pfs:CreatePath({
AgentCanClimb = true,
})
local wpIdx = 1
local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
local humrp = char.HumanoidRootPart
local db = false
local function findTarget()
local players = game.Players:GetPlayers()
local MaxDistance = 9999999999
local nearestTarget
for i,v in pairs(players) do
if (v.Character) then
local target = v.Character
local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude
if (distance < MaxDistance) then
nearestTarget = target
MaxDistance = distance
end
end
end
return nearestTarget
end
local function followPath(goal)
db = true
path:ComputeAsync(hrp.Position, goal.Position)
wps = {}
if path.Status == Enum.PathStatus.Success then
wps = path:GetWaypoints()
wpIdx = 1
print(wps[wpIdx].Position)
hum:MoveTo(wps[wpIdx].Position)
task.wait(0.5)
db = false
end
end
hum.MoveToFinished:Connect(function(reached)
if reached and wpIdx < #wps then
wpIdx += 1
if wps[wpIdx].Action == Enum.PathWaypointAction.Jump then
hum.Jump = true
end
hum:MoveTo(wps[wpIdx].Position)
end
end)
path.Blocked:Connect(function(blockedWpIDX)
if blockedWpIDX > wpIdx then
local target = findTarget(script.Parent.HumanoidRootPart)
if target ~= nil then
followPath(target.Torso, target)
end
end
end)
game:GetService("RunService").Heartbeat:Connect(function(deltatime)
local target = findTarget(script.Parent.HumanoidRootPart)
if target ~= nil and db == false then
followPath(target.Torso, target)
end
end)
EDIT:
The twitching and stuff might be able to be entirely gone if you found the path, made the dummy get to the end of the path, then make the path again, and repeat.
Sorry if I worded it a bit weird, but you could just change your current code to make the debounce turn to false after looping through the waypoint table and moving to each, so then it would make another path.
I don’t really know how to explain it, sorry.
local pfs = game:GetService("PathfindingService")
local wps = {}
local path = pfs:CreatePath({
AgentCanClimb = true,
})
local wpIdx = 1
local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
local humrp = char.HumanoidRootPart
local db = false
local function findTarget()
local players = game.Players:GetPlayers()
local MaxDistance = 9999999999
local nearestTarget
for i,v in pairs(players) do
if (v.Character) then
local target = v.Character
local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude
if (distance < MaxDistance) then
nearestTarget = target
MaxDistance = distance
end
end
end
return nearestTarget
end
local function followPath(goal)
db = true
path:ComputeAsync(hrp.Position, goal.Position)
wps = {}
if path.Status == Enum.PathStatus.Success then
wps = path:GetWaypoints()
for i,v in pairs(wps) do
wpIdx += 1
if i < #wps then
if wps[i].Action == Enum.PathWaypointAction.Jump then
hum.Jump = true
end
hum:MoveTo(wps[i].Position)
hum.MoveToFinished:Wait()
else
db = false
end
end
end
end
path.Blocked:Connect(function(blockedWpIDX)
if blockedWpIDX > wpIdx then
local target = findTarget(script.Parent.HumanoidRootPart)
if target ~= nil then
followPath(target.Torso, target)
end
end
end)
game:GetService("RunService").Heartbeat:Connect(function(deltatime)
local target = findTarget(script.Parent.HumanoidRootPart)
if target ~= nil and db == false then
followPath(target.Torso, target)
end
end)
I think the little run animation is something your doing,
to fix the catching up issue,
check if the players CFrame has changed ever waypoint, if it changed, recalculate the path.