Auto Updating Pathfinding AI?

Hi. I have a simple pathfinding script but with 1 issue. if the enemy moves the ai goes to its previous position rather than going torwards the enemy. How would I make it to where it updates constantly until it reaches its goal?

function FollowPath (finalPosition,unit,Enemy)
    local unitPath = pathFindingService:CreatePath()
    unitPath:ComputeAsync(unit.HumanoidRootPart.Position, finalPosition)

    if unitPath.Status == Enum.PathStatus.Success then
        local waypoints = unitPath:GetWaypoints()

        for i, v in pairs (waypoints) do
            unit.Humanoid:MoveTo(v.Position)
            unit.Humanoid.MoveToFinished:Wait()
            if v.Action == Enum.PathWaypointAction.Jump then
                unit.Humanoid.Jump = true
            end
            if (waypoints[#waypoints].Position - finalPosition).magnitude > 15 then
                break
            end
            
            if (Enemy.HumanoidRootPart.Position - script.Parent.HumanoidRootPart.Position).Magnitude < 5 then return end
            if Enemy.Humanoid.Health == 0 then return end
        end
    end
end

You can loop the function which will fix your problem but the ai will only create a new path when it finishes its current one.

I made the following script for one of my games, it check if it can directly see the player if so then it moves towards them, otherwise it calculates a path which obviously takes more resources.


-- config --
local detectionDistance = 200 --studs

local humanoid = script.Parent:FindFirstChildWhichIsA("Humanoid")
local AI_head = script.Parent:FindFirstChild("Head")
local pathfinding_Service = game:GetService("PathfindingService")

wait(1)

local function findTarget()
	local target = nil
	for _, v in pairs(game.Players:GetChildren()) do
		if (v.Character.Head.Position - AI_head.Position).Magnitude < detectionDistance then
			if v.Character:FindFirstChild("Humanoid").Health > 0 then
				target = v.Character.HumanoidRootPart
			end
		else
			target = nil			
		end
	end
	return target
end


while wait(.1) do
	local target = findTarget()
	if target then
		local ray = Ray.new(AI_head.Position, (target.Position - AI_head.Position).Unit * detectionDistance)
		local hit, position = workspace:FindPartOnRayWithIgnoreList(ray,{script.Parent})

		if hit then
			if hit:IsDescendantOf(target.Parent) then
				humanoid:MoveTo(target.Position)
			else
				humanoid:MoveTo(target.Position)
				wait(.1)
				local path = pathfinding_Service:FindPathAsync(AI_head.Position, target.Position)
				local pathWaypoints = path:GetWaypoints()
				if path.Status == Enum.PathStatus.Success then
					for _, v in pairs(pathWaypoints) do
						humanoid:MoveTo(v.Position)
						humanoid.MoveToFinished:Wait(.1)
						if v.Action == Enum.PathWaypointAction.Jump then
							humanoid.Jump = true
						end
						if (pathWaypoints[#pathWaypoints].Position - target.Position).Magnitude > 15 then
							break
						end
					end
				else
					humanoid:MoveTo(target.Position)
				end
			end
		end
	end
end

3 Likes

The target variable is defined to the HumanoidRootPart if you check the findTarget() function you’ll see that it returns the rootPart.