What do you want to achieve? i want to find the the closest target from a targets list
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
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
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?
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’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.
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
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)
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.