I want to make a game like combat initiation where npcs follow you and attack you but the ai seems to be going straight to the player instead of going in its path. This causes the npc to run into walls
current code:
local PFS = game:GetService("PathfindingService")
local zombie = script.Parent
local humanoid = zombie:WaitForChild("Humanoid")
local humanoidRootPart = zombie:WaitForChild("HumanoidRootPart")
local PositionTorso = humanoidRootPart.Position
zombie.Head:SetNetworkOwner(nil)
local function testPart(pos)
local part = Instance.new("Part")
part.CanCollide = false
part.CanQuery = false
part.Transparency = 0.5
part.Anchored = true
part.Position = pos
part.Parent = game.Workspace
game:GetService("Debris"):AddItem(part, 2)
end
function findNearestTorso(pos)
local list = game.Workspace:children()
local torso = nil
local dist = 100000000
local temp = nil
local human = nil
local temp2 = nil
for x = 1, #list do
temp2 = list[x]
if (temp2.className == "Model") and (temp2 ~= script.Parent) then
temp = temp2:findFirstChild("Torso")
human = temp2:findFirstChild("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
if (temp.Position - pos).magnitude < dist then
torso = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return torso
end
local function getPath(position)
local path = PFS:CreatePath()
path:ComputeAsync(zombie.Head.Position, position)
return path
end
local function walkTo(position)
local path = getPath(position)
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
for index, waypoint in pairs(waypoints) do
if path:GetWaypoints()[index].Action == Enum.PathWaypointAction.Jump then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
testPart(waypoints[index].Position)
humanoid:MoveTo(waypoints[index].Position)
end
end
end
while true do
local target = findNearestTorso(PositionTorso)
if target ~= nil then
walkTo(target.Position)
end
PositionTorso = humanoidRootPart.Position
task.wait(0.15)
end
Npc need time to arrive the current waypoint before going for the next one, without waiting for arrival, it will skip everything and go straight for the last waypoint.
local zombie = script.Parent
local humanoid = zombie:WaitForChild("Humanoid")
local humanoidRootPart = zombie:WaitForChild("HumanoidRootPart")
local PositionTorso = humanoidRootPart.Position
zombie.Head:SetNetworkOwner(nil)
local function testPart(pos)
local part = Instance.new("Part")
part.CanCollide = false
part.CanQuery = false
part.Transparency = 0.5
part.Anchored = true
part.Position = pos
part.Parent = game.Workspace
game:GetService("Debris"):AddItem(part, 2)
end
function findNearestTorso(pos)
local list = game.Workspace:children()
local torso = nil
local dist = 100000000
local temp = nil
local human = nil
local temp2 = nil
for x = 1, #list do
temp2 = list[x]
if (temp2.className == "Model") and (temp2 ~= script.Parent) then
temp = temp2:findFirstChild("Torso")
human = temp2:findFirstChild("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
if (temp.Position - pos).magnitude < dist then
torso = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return torso
end
local function getPath(position)
local path = PFS:CreatePath({AgentCanJump = true})
path:ComputeAsync(zombie.Head.Position, position)
return path
end
local function walkTo(position)
local path = getPath(position)
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
if waypoints[2].Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
humanoid:MoveTo(waypoints[2].Position)
humanoid.MoveToFinished:Wait()
for index, waypoint in pairs(waypoints) do
testPart(waypoints[index].Position)
end
end
end
while true do
local target = findNearestTorso(PositionTorso)
if target ~= nil then
walkTo(target.Position)
end
PositionTorso = humanoidRootPart.Position
task.wait()
end```
I am not getting what I want im sorry if im being dumb but now the npc jumps but it cant get over simple obstacles because once it jumps over it it will start jumping endlessly without walking (the parts in between us are waypoints)
Using loop for waypoints don’t work well, try SimplePath or NoobPath, those resources already implemented a signal-based pathfinding system, and it’s generally easier to use compared to coding your own.
The Npc was going to the old position probably because the loops, the loop won’t stop until each waypoint is reached, then you start a new loop every 0.15 seconds, there will be multiple loops running at the same time, each telling the npc to go to a certain waypoint, potentially including waypoints from the previous path directing to the old position.
For the new version, you ignore all waypoints, only go to the second waypoint and computing new path every frame, however if the second waypoint is jump, the npc will move to that waypoint and try to do that. While the roblox pathfinding isn’t perfect, under complex environment like stairs, it might generate a waypoint that’s super close to the Npc as the second waypoint, which the npc might reach instantly, signaling Move Finished and jumps, then this repeats the next frame, causing endless jumping.
← Calculating path(s) every frame is not ideal, just several Npcs doing that can make everything slowdown