AI chase pathfinding script issue

I have the following script that has these issues:

  1. The NPC chasing you around updates late, it will finish the whole path before it changes, it should constantly be finding the best way to chase you

  2. After it stops chasing you its pathfinding breaks and it starts running into walls

task.wait(1)

local PathfindingService = game:GetService("PathfindingService")


local AI = script.Parent
local RP = script.Parent.HumanoidRootPart
local Hum = script.Parent.Humanoid

local Waypoints = game.Workspace:WaitForChild("Waypoints"):GetChildren()

RP:SetNetworkOwner(nil)

local attackAnim = Hum.Animator:LoadAnimation(script.Attack)

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {Hum}

local Damage = 25
local AttackRange = 5


local pathParams = {
	AgentHeight = 5,
	AgentRadius = 3,
	AgentCanJump = true,
}

local function getPath(destination)
	local path = PathfindingService:CreatePath(pathParams)

	path:ComputeAsync(RP.Position, destination)

	return path	
end

function getTarget()

	local closestTarget
	local distanceFromClosestTarget = 1000000000

	for i, player in pairs(game.Players:GetChildren()) do
		local distance = (player.Character.HumanoidRootPart.Position - RP.Position).Magnitude

		if distance < distanceFromClosestTarget then
			distanceFromClosestTarget = distance
			closestTarget = player
		end
	end


	return(closestTarget)
end

function chaseTarget(target)
	local path = PathfindingService:CreatePath(pathParams)

	path:ComputeAsync(RP.Position, target.Character.HumanoidRootPart.Position)

	for i, waypoint in pairs(path:GetWaypoints()) do
		if (target.Character.HumanoidRootPart.Position - RP.Position).Magnitude <= 45 then
			print((target.Character.HumanoidRootPart.Position - RP.Position).Magnitude)
			Hum:MoveTo(waypoint.Position)

			if (target.Character.HumanoidRootPart.Position - RP.Position).Magnitude <= AttackRange then
				attackAnim:Play()
				target.Character.Humanoid.Health -= Damage
				if target.Character.Humanoid.Health <= 0 then
					print("fired from mid of chaseTargert")
					getTarget()
					break
				end
			end
			Hum.MoveToFinished:Wait()
		else

			break
		end
	end
end

function moveTo(target)
	local path = getPath(target)

	if path.Status == Enum.PathStatus.Success then
		for i, waypoint in pairs(path:GetWaypoints()) do

			local target = getTarget()
			if (target.Character.HumanoidRootPart.Position - RP.Position).Magnitude <= 45 and target.Character.Humanoid.Health > 0 then

				chaseTarget(target)
			else
				Hum:MoveTo(waypoint.Position)
				Hum.MoveToFinished:Wait()

			end
		end



	end
end


function patrol()
	print("fired")
	local ChosenWapoint = math.random(1, #Waypoints)
	moveTo(game.Workspace.Waypoints:FindFirstChild(ChosenWapoint).Position)
end



while task.wait(0.2) do
	patrol()
end

Instead of iterating through the entire table of waypoints, you could recalculate the path after a MoveToFinished event. A way to do this would be to only use the first 3 waypoints in your table. After the AI reaches the second waypoint, calculate a new path from the third waypoint’s position to the player. Then switch over to that new path it’s finished.

1 Like

Alright thanks ill try that

,

I didn’t do exactly what you told me to do but you gave me a very good idea on what to do and as I only got the idea due to this reply you’re getting the solution

functional code(the npc doesn’t damage you but ill implement that later)

task.wait(1)

local PathfindingService = game:GetService("PathfindingService")


local AI = script.Parent
local RP = script.Parent.HumanoidRootPart
local Hum = script.Parent.Humanoid

local Waypoints = game.Workspace:WaitForChild("Waypoints"):GetChildren()

RP:SetNetworkOwner(nil)

local attackAnim = Hum.Animator:LoadAnimation(script.Attack)

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {Hum}

local Damage = 25
local AttackRange = 5


local pathParams = {
	AgentHeight = 5,
	AgentRadius = 3,
	AgentCanJump = true,
}

local function getPath(destination)
	local path = PathfindingService:CreatePath(pathParams)

	path:ComputeAsync(RP.Position, destination)

	return path	
end

function getTarget()

	local closestTarget
	local distanceFromClosestTarget = 1000000000

	for i, player in pairs(game.Players:GetChildren()) do
		local distance = (player.Character.HumanoidRootPart.Position - RP.Position).Magnitude

		if distance < distanceFromClosestTarget then
			distanceFromClosestTarget = distance
			closestTarget = player
		end
	end


	return(closestTarget)
end

function chaseTarget(target)
	
	print("chase started")
	local path
	
	path = getPath(target.Character.HumanoidRootPart.Position)
	
	local waypoints = path:GetWaypoints()
	
		Hum:MoveTo(waypoints[2].Position)
		--Hum.MoveToFinished:Wait()
		
	if (target.Character.HumanoidRootPart.Position - RP.Position).Magnitude <= 45 and target.Character.Humanoid.Health > 0 then
		local path = PathfindingService:CreatePath(pathParams)
		path:ComputeAsync(RP.Position, target.Character.HumanoidRootPart.Position)
	else
		return
	end
	
end

function moveTo(target)
	local path = getPath(target)

	if path.Status == Enum.PathStatus.Success then
		for i, waypoint in pairs(path:GetWaypoints()) do

			local target = getTarget()
			if target and (target.Character.HumanoidRootPart.Position - RP.Position).Magnitude <= 45 and target.Character.Humanoid.Health > 0 then
				path:Destroy()
				chaseTarget(target)
				--break
			else
				Hum:MoveTo(waypoint.Position)
				Hum.MoveToFinished:Wait()

			end
		end



	end
end


function patrol()
	print("fired")
	local ChosenWapoint = math.random(1, #Waypoints)
	moveTo(game.Workspace.Waypoints:FindFirstChild(ChosenWapoint).Position)
end



while task.wait(0.2) do
	patrol()
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.