Hi,
I have been trying to make pathfinding work on my enemy NPC for hours now (so that I can add more complex maps)
I came across a couple of issues, but I got it to work somewhat. Here is the current code on the pathfinding part. (sorry if it’s kind of messy I have been trying for a while) (the enemy runs off 1 script)
CollectionService:GetInstanceAddedSignal("Enemy"):Connect(function(enemyChar)
local humanoid = enemyChar:FindFirstChild("Enemy")
local torso = enemyChar:FindFirstChild("HumanoidRootPart")
local targetPlayer = enemyChar:FindFirstChild("targetPlayer")
wait()
torso:SetNetworkOwner(nil)
RunService.Heartbeat:Connect(function()
if (enemyChar ~= nil) and (humanoid.Health > 0) and (ReplicatedStorage.playersLeft.Value > 0) and (Workspace:FindFirstChild(targetPlayer.Value) ~= nil) and (Workspace[targetPlayer.Value].Humanoid.Health > 0) and (Workspace[targetPlayer.Value].inGame.Value == true) then
local pathParameters = {
AgentHeight = 5,
AgentRadius = 4,
AgentCanJump = false
}
local path = game:GetService("PathfindingService"):CreatePath(pathParameters)
path:ComputeAsync(torso.Position,game.Workspace[targetPlayer.Value].HumanoidRootPart.Position)
local points = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for i,v in pairs(points) do
if((points[#points].Position) - (Workspace[targetPlayer.Value].HumanoidRootPart.Position)).magnitude > 10 then
break
end
if v.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
humanoid:MoveTo(v.Position)
local timeout = humanoid.MoveToFinished:Wait(0.5)
if not timeout then
humanoid.Jump = true
break
end
end
else
humanoid:MoveTo(Workspace[targetPlayer.Value].Head.Position, Workspace[targetPlayer.Value].Head)
end
end
end)
end)
I originally did not want to use RunService as I want to minimise the amounts of loops I use as it can get laggy however this was the only solution which worked the best so far. I have tried to enclose everything in a function and call it again and break it if the player moves too far from the last waypoint but for some reason, it results in the NPC not moving altogether after it detects that the player moved too far from the last waypoint.
This is the only issue that remains:after moving and kiting the enemy for a while, it sometimes just gets stuck on the side of the bridge. Sometimes it will target me again when I get close but most of the time it’s stuck there forever. I have no idea why it does this. There is no error in the output. It should at least MoveTo my head position according to the code.
Any ideas as to why it does this? Or can anyone improve on my pathfinding code, it’s definitely not great. I have been looking through the forums and videos on pathfinding and just trying it until it kind of works.
Thanks in advance.
optional issues to solve:
any ideas on how to make pathfinding work properly without RunService?
I tried adding a raycast check (so that it would pathfind only when necessary) but the movement was so choppy like the npc couldn’t decide whether it would pathfind or move. (sample code below) How do I make it not as choppy?
local ray = Ray.new(torso.Position, (Workspace[targetPlayer.Value].Head.Position - torso.Position).Unit * 400)
local hit,position = workspace:FindPartOnRayWithIgnoreList(ray,Workspace.currentMap:GetDescendants())
if hit then
if hit.Parent:IsDescendantOf(Workspace[targetPlayer.Value]) and math.abs(hit.Position.Y - torso.Position.Y) < 3 then
humanoid:MoveTo(Workspace[targetPlayer.Value].Head.Position, Workspace[targetPlayer.Value].Head)
else
--insert pathfinding code
end
end