AI randomly stops before reaching player

Hello, I made an NPC that runs after the player and damages them when he gets near them. However, sometimes, he randomly stops before he even reaches the player. I’ve tried printing what step he’s in when he does this but I’m not sure. Any feedback is appreciated too!

PathFindingService = game:GetService("PathfindingService")
Grab1 = script.Parent.Humanoid:LoadAnimation(script.Grab)
Grab2 = script.Parent.Humanoid:LoadAnimation(script.Grab2)
function AttackFunction(TargetCharacter)
	local RandomAnimation = math.random(1,2)
	if RandomAnimation == 1 then
		Grab1:Play()
		wait(.5)
		TargetCharacter.Humanoid:TakeDamage(25)
	else
		Grab2:Play()
		wait(.5)
	TargetCharacter.Humanoid:TakeDamage(25)
	end
end
function FindNearest()
	print("started")
    local lowest = math.huge 
    local NearestPlayer = nil
    for i,v in pairs(game.Players:GetPlayers()) do 
        if v.Character and v.Character.Humanoid.Health > 0 then
			local position = script.Parent.HumanoidRootPart.Position
            local distance = v:DistanceFromCharacter(position)
           	if distance < lowest then
                lowest = distance
                NearestPlayer = v
            end
        end
    end
	print(NearestPlayer)
	if NearestPlayer == nil then
		wait(1)
		FindNearest()
	end
    local path = PathFindingService:CreatePath()
	local HumanoidRootPart = script.Parent.HumanoidRootPart
	local TargetCharacter = NearestPlayer.Character
	path:ComputeAsync(HumanoidRootPart.Position,TargetCharacter.HumanoidRootPart.Position)
	if path.Status == Enum.PathStatus.Success then
	     wayPoints = path:GetWaypoints() 
	else
		wait()
		FindNearest()
	end
	print("computing waypoint")
	for i,v in pairs(wayPoints) do
		print("going to waypoints")
	script.Parent.Humanoid:MoveTo(v.Position)
		    if v.Action == Enum.PathWaypointAction.Jump then
                script.Parent.Humanoid.Jump = true
            end
		local MoveToWait = script.Parent.Humanoid.MoveToFinished:Wait(1)
		if not MoveToWait or path.Blocked == true or (HumanoidRootPart.Position - wayPoints[1].Position).magnitude > 20 then
	        script.Parent.Humanoid.Jump = true
			break
		end
		if (HumanoidRootPart.Position - TargetCharacter.HumanoidRootPart.Position).Magnitude <= 5 and TargetCharacter.Humanoid.Health > 0 then
			AttackFunction(TargetCharacter,HumanoidRootPart)
			print("near player")
		end
	end
	while (HumanoidRootPart.Position - TargetCharacter.HumanoidRootPart.Position).Magnitude <= 5 and TargetCharacter.Humanoid.Health > 0  do wait()
		print("target player found before loop restarted")
		AttackFunction(TargetCharacter,HumanoidRootPart)
	end
	FindNearest()
end
FindNearest()
2 Likes

Your code is doing recursive method-calls, without a proper/quick stop condition. - So your code most likely ends up with a ‘stack overflow’ error.

-- Wrong code, will fail at some point, when stack-memory is used up
function FindNearest()
[..]
   FindNearest()
[..]
end

Change your code, so it does it in an iterative way instead:

local function FindNearest()
  local nearestPlayer = nil
  -- .. code here that tries to locate the nearest player
  return nearestPlayer
end

-- Iterative
while nil ~= script.Parent do
  local nearestPlayer = FindNearest()
  if nil ~= nearestPlayer then
    -- .. call another method, that does something with the found `nearestPlayer`
  end
  wait(1)
end

Also you should check if the TargetCharacter is “still there”. Perhaps the player’s character has left or died.

2 Likes