Help with AI / Pathfindings

Hey guys, I need some helpful help if you can.
Here’s the thing, I have the enemy AI done on pathfindings, etc.

He follows and goes around barriers, but I want him to stop following at a certain distance from the player (MoveTo) and so when the player leaves that distance, the enemy will follow again

Example: The enemy’s sight distance is 200 (more I will change), he will follow the player, so when he is at a distance of 20 for example, he will stop and attack the player (as if he were an archer).
Can someone help me?

local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local lowerTorso = script.Parent:WaitForChild("LowerTorso")
local clone = script.Parent:Clone()
local distSee = 20
local distAttack = 5

function findPath(target)
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position,target.Position)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			myHuman:MoveTo(waypoint.Position)
			local timeOut = myHuman.MoveToFinished:Wait(1)
			if not timeOut then
				myHuman.Jump = true
				--print("Caminho muito longo!")
				findPath(target)
				break
			end
			if checkSight(target) then
				repeat
					--print("Movendo-se diretamente para o alvo")
					myHuman:MoveTo(target.Position)
					attack(target)
					wait(0.1)
					if target == nil then
						break
					elseif target.Parent == nil then
						break
					end
				until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
				break
			end
			if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
				--print("O alvo mudou, gerando um novo caminho")
				findPath(target)
				break
			end
		end
	end
end

function checkSight(target)
	local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
	local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
	if hit then
		if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
			--print("Eu posso ver o alvo")
			return true
		end
	end
	return false
end

function findTarget()
	local target = nil
	local potentialTargets = {}
	local seeTargets = {}
	for i,v in ipairs(workspace:GetChildren()) do
		local human = v:FindFirstChild("Humanoid")
		local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if human and torso and v.Name ~= script.Parent.Name then
			if (myRoot.Position - torso.Position).magnitude < distSee and human.Health > 0 then
				table.insert(potentialTargets,torso)
			else
				myHuman:MoveTo(script.Spawn.Position)
			end
		end
	end
	if #potentialTargets > 0 then
		for i,v in ipairs(potentialTargets) do
			if checkSight(v) then
				table.insert(seeTargets, v)
			elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < distSee then
				target = v
				distSee = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if #seeTargets > 0 then
		for i,v in ipairs(seeTargets) do
			if (myRoot.Position - v.Position).magnitude < distSee then
				target = v
				distSee = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if target then
		if math.random(20) == 1 then
		end
	end
	return target
end

function attack(target)
	if (myRoot.Position - target.Position).magnitude < distAttack then
		if target.Parent ~= nil then
			target.Parent.Humanoid:TakeDamage(25)
		end
		wait(0.4)
	end
end

function died()
	wait(5)
	clone.Parent = workspace
	game:GetService("Debris"):AddItem(script.Parent,0.1)
end

myHuman.Died:Connect(died)

lowerTorso.Touched:Connect(function(obj)
	if not obj.Parent:FindFirstChild("Humanoid") then
		myHuman.Jump = true
	end
end)

function main()
	local target = findTarget()
	if target then
		myHuman.WalkSpeed = 16
		findPath(target)
	else
		myHuman.WalkSpeed = 8

	end
end

while wait(0.1) do
	if myHuman.Health < 1 then
		break
	end
	main()
end
1 Like

You can get the magnitude between the player and the AI to figure out their distance

I have the distance here

function attack(target)
	if (myRoot.Position - target.Position).magnitude < distAttack then
		if target.Parent ~= nil then
			target.Parent.Humanoid:TakeDamage(25)
		end
		wait(0.4)
	end
end

And in this part there’s the moveTo and the attack function, but I need a way that I don’t need to put the distance in the attack function, but where it is called, for example:

if checkSight(target) then
				repeat

					myHuman:MoveTo(target.Position) -- Here the player is already in the enemy's view

-- Between these parts I want the enemy to stop at pathfinding to attack, and if the player leaves that distance he will follow him again --

					attack(target) --Here is the attack function
					wait(0.1)
					if target == nil then
						break
					elseif target.Parent == nil then
						break
					end
				until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
				break
			end