How to find the closest target from the targets list?

  1. What do you want to achieve? i want to find the the closest target from a targets list

  2. What is the issue? i made a script thats finds nearest target from the list, but when npc finds a target, npc just focuses on it, until the target is dead or npc cant reach target, i meant when it cant create path beetwen the npc and target. Also, if target is dead or cant reachable, its just freezes. But if other targets gets close up to npc, its follows them.
    I hope I explained well

  3. What solutions have you tried so far? i looked up to devform but i cant found ;/

by the way, here is my code:

local function findTarget()
	local targets = workspace.RedTeamSoldiers:GetChildren()
	if #targets ~= 0 then
		local maxDistance = 10000
		local nearestTarget
		if targets then
			for i, t in pairs(targets) do
				if t.Humanoid.Health > 0 then
					local distance = (soldier.HumanoidRootPart.Position - t.HumanoidRootPart.Position).Magnitude
					if distance < maxDistance then
						nearestTarget = t
						maxDistance = distance

					end

				else
					t.Parent = workspace.DiedSoldiers
				end

			end
		else	
			nearestTarget = nil
		end
		if not nearestTarget then
			nearestTarget = nil
		end
		return nearestTarget
	end
end


local function patrol()
	local targetList = workspace.RedTeamSoldiers:GetChildren()
	if #targetList > 0 then
		local target = findTarget()
		if target then
			walkTo(target)
		end
	end
	wait(0.1)
end

while true do
	patrol()
end
1 Like

can someone help? how to find closest target? :confused:

You need Pathfinding if you want a proper AI that can follow. You also need to check if the humanoid is alive inside the patrol function.

i already made ai, the problem is target finding

the issue is its not finding closest target

I haven’t tested it but your script looks correct. It should be finding the closest target from inside RedTeamSoldiers. Have you tried looking at the OutPut for any errors?

Yes, its gets targets from RedTeamSoldiers folder, but there isnt a error in output

i made a script thats finds nearest target from the list, but when npc finds a target, npc just focuses on it, until the target is dead or npc cant reach target, i meant when it cant create path beetwen the npc and target. Also, if target is dead or cant reachable, its just freezes. But if other targets gets close up to npc, its follows them.

i explained this issue above

I’m having a hard time understanding the issue, in your paragraph you say:

npc just focuses on it, until the target is dead or npc cant reach target

which I assume then that once the above condition is met, you make the ai get another target (and it seems to me in your code that it does, except for any detection for unreachable path?) but you then say it freezes?

I don’t get it especially since your code is designed to locate the closest target in a loop

Also, if target is dead or cant reachable, its just freezes.

I captured video, look at that, 2023-02-17 20-29-22

also, there is my full code ;-;

local soldier = script.Parent
local humanoid = soldier.Humanoid
local pathfindingservice = game:GetService("PathfindingService")
local runservice = game:GetService("RunService")
soldier.PrimaryPart:SetNetworkOwner(nil)

local function createPath(destination)
	local pathfindingservice = game:GetService("PathfindingService")
	local pathParameters = {
		AgentHeight = 5.162,
		AgentRadius = 2,
		AgentCanJump = false
		
		
	}
	local path = pathfindingservice:CreatePath(pathParameters)
	path:ComputeAsync(soldier.HumanoidRootPart.Position, destination.HumanoidRootPart.Position)
	
	for i, w in pairs(workspace.waypoints:GetChildren()) do
		w:Destroy()
	end
	local waypoints = path:GetWaypoints()
	for i, w in pairs(waypoints) do
		local waypoint = Instance.new("Part")
		waypoint.Name = tostring(table.find(waypoints,w))
		waypoint.Position = w.Position
		waypoint.CanCollide = false
		waypoint.Parent = workspace.waypoints
		waypoint.Shape = "Ball"
		waypoint.Size = Vector3.new(1, 1, 1)
		waypoint.Anchored = true
	end

	return path
end

local function walkTo(destination)
	while true do
		if destination.Humanoid.Health > 0 then
			local path = createPath(destination)
			local waypoints = path:GetWaypoints() 
			if waypoints[2] then
				humanoid:MoveTo(waypoints[2].Position)
			else 
				break
			end
			soldier.Torso.Touched:Connect(function(hit)
				if hit.Parent == destination then
					destination.Humanoid.Health = 0
				end
			end)
		else
			break
		end
	end
	
end


local function findTarget()
	local targets = workspace.RedTeamSoldiers:GetChildren()
	if #targets ~= 0 then
		local maxDistance = 10000
		local nearestTarget
		if targets then
			for i, t in pairs(targets) do
				if t.Humanoid.Health > 0 then
					local distance = (soldier.HumanoidRootPart.Position - t.HumanoidRootPart.Position).Magnitude
					if distance < maxDistance then
						nearestTarget = t
						maxDistance = distance

					end

				else
					t.Parent = workspace.DiedSoldiers
				end

			end
		else	
			nearestTarget = nil
		end
		if not nearestTarget then
			nearestTarget = nil
		end
		return nearestTarget
	end
end


local function patrol()
	local targetList = workspace.RedTeamSoldiers:GetChildren()
	if #targetList > 0 then
		local target = findTarget()
		if target then
			walkTo(target)
		end
	end
	wait(0.1)
end

while true do
	patrol()
end


1 Like

You have a while loop calculating the path that’s locked onto one target. It wont find another target until the loop is finished.

I see now, the walkto remains in the loop, so it will ignore additional targets even if they are really close,

why it freezes? well its because its still trying to pathfind to the closest target but its physically impossible for it so it freezes. it will constantly end the walkto loop and thats why in this instance you can swap targets (because the loop is constantly ending)

@Kamran3478

you need to signal the script so that when a closer target is identified, you go to it and stop following the other target (thus breaking the loop)

for the 2nd, check if #waypoints == 0 (or if the ai velocity == 0?) and you know you then cant reach the current target.

then do i need to disconnect the walkto function when target changed?

I don’t know if this is the ideal way of doing things but you can separate the pathfinding script from the findtarget script, and when a new target is found you can assign it to an ObjectValue inside the AI. For the pathfinding script you can set the destination to the ObjectValue

path:ComputeAsync(soldier.HumanoidRootPart.Position, ObjectValue.Value.Position) --Assuming you set the Value to HumanoidRootPart

I solved it, here is the solution:
I created a table and named it blocked targets. Npc gets a target and follows it and signals if there is no path and puts the target in the table of blocked targets, which is npc cannot create a path between this target and tries again and again. Also, the findtarget function checks whether the found target is in the blocked targets, checks whether it can create a path with it, and if it can, it removes the blocked target from the table.

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