I’m having some trouble trying to figure out how to update the path of an NPC that targets the player, (Nearest, but that’s not implemented yet so it’s not in the code example)
Currently, the NPC will just go to the last known position of the player, obviously because it wants to finish the for loop first, but I want it to update its path at least relatively frequently/when the player is outside of the range of the last waypoint.
local players = game:GetService("Players")
local RunService = game:GetService('RunService')
local human = script.Parent:WaitForChild("Humanoid")
local body = script.Parent:WaitForChild("HumanoidRootPart")
local pathParams = {
["AgentHeight"] = 8,
["AgentRadius"] = 5,
["AgentCanJump"] = false
}
function pathToNearestPlayer()
local PlayerPath = pathFindingService:CreatePath(pathParams)
for _,plr in pairs(players:GetPlayers()) do
local char = plr.Character
local playerRoot = char:FindFirstChild("HumanoidRootPart")
local playerPos = playerRoot.Position
PlayerPath:ComputeAsync(body.Position,playerPos)
end
return PlayerPath
end
--I mainly added wait here temporarily since the code runs into an error if it runs without a player present
wait(4)
while true do
path = pathToNearestPlayer()
local waypoints = path:GetWaypoints()
for i, waypoint in pairs(waypoints) do
path = pathToNearestPlayer()
human:MoveTo(waypoint.Position)
human.MoveToFinished:Wait(1)
end
end
I have attempted the latter of comparing the distance of the player and the last waypoint and trying to break the loop with that, but any case where break is used in the for loop seems to completely break the NPC’s ability to move at all.
Does anyone have any advice? I’m at a loss.
I’m aware that this has been posted a lot, but as it stands none of the solutions I’ve seen nor have any of the videos supplied in other threads in regards to this issue have been understandable to me, kind of a me issue there so, apologies.
If it matters at all, it’s intended as an enemy script, so I’d need them to get close to attack.
Alright, I threw it in with a target position, but it’s throwing this error at me;
“Workspace.Specimen 2.BasicMonsterHandle:59: attempt to get length of a PathWaypoint value”
Gonna be honest here, I don’t fully understand what’s going on in what you sent but an error was to be expected I suppose with me throwing it in haphazardly.
I’m relatively new to messing around with paths so I guess the confusion is normal. How would I go around fixing the error though?
however, it doesn’t seem to be interrupting the loop and only triggers when the player is WAY far away from the NPC, or just, inconsistently in general, triggering when I’m standing still sometimes
local players = game:GetService("Players")
local RunService = game:GetService('RunService')
local human = script.Parent:WaitForChild("Humanoid")
local body = script.Parent:WaitForChild("HumanoidRootPart")
local pathParams = {
["AgentHeight"] = 8,
["AgentRadius"] = 5,
["AgentCanJump"] = false
}
local function getclosestplr()
local bot_position = body.Position
local distance = math.huge
local closest_player_character = nil
for _,plr in pairs(players:GetPlayers()) do
local player = plr.Character
if player:FindFirstChild("Humanoid") then
local player_position = player.HumanoidRootPart.Position
local distance_from_bot = (bot_position - player_position).magnitude
if distance_from_bot < distance then
distance = distance_from_bot
closest_player_character = player
end
end
end
return closest_player_character
end
function pathToNearestPlayer()
local plr = getclosestplr()
local PlayerPath = pathFindingService:CreatePath(pathParams)
PlayerPath:ComputeAsync(body.Position,plr.HumanoidRootPart.Position)
return PlayerPath
end
wait(6)
while true do
path = pathToNearestPlayer()
local waypoints = path:GetWaypoints()
for i, waypoint in pairs(waypoints) do
human:MoveTo(waypoint.Position)
human.MoveToFinished:Wait()
local plr = getclosestplr()
if i > 8 and (plr.HumanoidRootPart.Position - waypoints[#waypoints].Position).Magnitude > 1 then
-- recalculate path
print ("Recalculating path")
break
end
end
end```
Different from the one before specifically to fix finding the closest player, also so I could use it in your if statement to get the player's HRP pos.
The wait is there since my player needs to spawn otherwise getting player returns nill, it’s just temporary for the most part but I don’t think it’d affect it given it’s before the while loop.
Strange that it’s working for you though… Is the positioning of the if statement wrong in my script by chance? Like would it need to come before movetofinished or moveto?
while true do
local target = require(script.Parent.Targets).findNearestTarget()
if target then
local path = pfs:CreatePath()
path:ComputeAsync(npc.PrimaryPart.Position, target.PrimaryPart.Position)
local waypoints = path:GetWaypoints()
for _, waypoint in waypoints do
local distanceToPlayer = (target.PrimaryPart.Position - npc.PrimaryPart.Position).Magnitude
print("Peter is", math.round(distanceToPlayer), "studs away from", target.Name)
if (waypoints[#waypoints].Position - target.PrimaryPart.Position).Magnitude > 2 then
break
end
if distanceToPlayer > 3 then
npc.Humanoid:MoveTo(waypoint.Position)
npc.Humanoid.MoveToFinished:Wait()
else
break
end
end
end
task.wait()
end