So pretty much I want these dummys to stop moving towards each other once they are a certain distance apart. Right now they keep running straight into each other then start flying up together
I need them to stop x amount of studs away from each other.
I’ve added a print statement in and I’ve noticed it’s not playing so I think my logic is flawed. Any help would be appreciated.
local function FindTarget(Team, Soldier)
local blockedConnection
local otherTeam
local waypoints
if Team == "Blue" then
otherTeam = "Red"
else
otherTeam = "Blue"
end
for i, soldier in pairs(game.Workspace:FindFirstChild(Team.."Soldiers"):GetChildren()) do
local path = PathfindingService:CreatePath({
AgentCanJump = true
})
local ClosestSoldier = 10000
local AttackSoldier = Instance.new("ObjectValue")
AttackSoldier.Parent = Soldier
for i, soldier in pairs(game.Workspace:FindFirstChild(otherTeam.."Soldiers"):GetChildren()) do
local HumanoidRootPart = soldier:FindFirstChild("HumanoidRootPart")
local value = (Soldier:FindFirstChild("HumanoidRootPart").Position - HumanoidRootPart.Position + Vector3.new(3, 0, 0)).Magnitude
if value < ClosestSoldier then
ClosestSoldier = value
AttackSoldier.Value = HumanoidRootPart
end
end
local success, errormessage = pcall(function()
path:ComputeAsync(Soldier.HumanoidRootPart.Position, AttackSoldier.Value.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
local breakLoop = false
for i, waypoint in pairs(waypoints) do
local humanoid = Soldier:FindFirstChild("Humanoid")
if breakLoop == true then
break
else
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Connect(function()
local magnitude = (AttackSoldier.Value.Position - Soldier.HumanoidRootPart.Position).Magnitude
if magnitude <= 5 then
print("Stopping troop to attack")
Attack(Team, Soldier, AttackSoldier.Value)
AttackSoldier:Destroy()
breakLoop = true
else
FindTarget(Team, Soldier)
end
end)
end
end
end
end
end
Theres no errors in the output and the problem is somewhere the for loop that loops through the way points.
you need to call Humanoid:MoveTo(waypoint.Position) after you create Connect Function . Otherwise the script will fire before you have even defined what to do when it MoveToFinished
for i, waypoint in pairs(waypoints) do
local humanoid = Soldier:FindFirstChild("Humanoid")
if breakLoop == true then
break
else
humanoid.MoveToFinished:Connect(function()
humanoid:MoveTo(waypoint.Position)
When I do that they don’t even start to move since they never got triggered to move in the first place so theres no event ever firing of the Humanoid.MoveToFinished.
How would I find the humanoid at the start of script tho
local ServerStorage = game:GetService("ServerStorage")
local PathfindingService = game:GetService("PathfindingService")
local Soldiers = ServerStorage.Soldiers
local BluxMaxTroops = 20
local RedMaxTroops = 10
local BlueTeamSpawnCooldown = 0
local RedTeamSpawnCooldown = 0
local function Attack(Team, Soldier, Enemy)
end
local function FindTarget(Team, Soldier)
local blockedConnection
local otherTeam
local waypoints
if Team == "Blue" then
otherTeam = "Red"
else
otherTeam = "Blue"
end
for i, soldier in pairs(game.Workspace:FindFirstChild(Team.."Soldiers"):GetChildren()) do
local path = PathfindingService:CreatePath({
AgentCanJump = true
})
local ClosestSoldier = 10000
local AttackSoldier = Instance.new("ObjectValue")
AttackSoldier.Parent = Soldier
for i, soldier in pairs(game.Workspace:FindFirstChild(otherTeam.."Soldiers"):GetChildren()) do
local HumanoidRootPart = soldier:FindFirstChild("HumanoidRootPart")
local value = (Soldier:FindFirstChild("HumanoidRootPart").Position - HumanoidRootPart.Position + Vector3.new(3, 0, 0)).Magnitude
if value < ClosestSoldier then
ClosestSoldier = value
AttackSoldier.Value = HumanoidRootPart
end
end
local success, errormessage = pcall(function()
path:ComputeAsync(Soldier.HumanoidRootPart.Position, AttackSoldier.Value.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
local breakLoop = false
for i, waypoint in pairs(waypoints) do
local humanoid = Soldier:FindFirstChild("Humanoid")
if breakLoop == true then
break
else
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Connect(function()
local magnitude = (AttackSoldier.Value.Position - Soldier.HumanoidRootPart.Position).Magnitude
if magnitude <= 5 then
print("Stopping troop to attack")
Attack(Team, Soldier, AttackSoldier.Value)
AttackSoldier:Destroy()
breakLoop = true
else
FindTarget(Team, Soldier)
end
end)
end
end
end
end
end
local function SpawnSoldier(Type, Team)
local soldier = Soldiers:FindFirstChild(Type):Clone()
soldier.Parent = game.Workspace:FindFirstChild(Team.."Soldiers")
soldier.HumanoidRootPart.CFrame = game.Workspace:FindFirstChild(Team.."Team").CFrame
local team = Instance.new("StringValue")
team.Name = Team
team.Value = Team
end
local function Soldiers(Team)
local soldiers = game.Workspace:FindFirstChild(Team.."Soldiers"):GetChildren()
if #soldiers <= 0 then
return
elseif #soldiers >= 1 then
for i, part in pairs(game.Workspace:FindFirstChild(Team.."Soldiers"):GetChildren()) do
FindTarget(Team, part)
end
task.wait()
Soldiers(Team)
end
end
game.Workspace.BlueSoldiers.ChildAdded:Connect(function()
Soldiers("Blue")
end)
game.Workspace.RedSoldiers.ChildAdded:Connect(function()
Soldiers("Red")
end)
local function Cooldown(Team)
if Team == "Blue" then
if BlueTeamSpawnCooldown == 0 then
return
else
BlueTeamSpawnCooldown -= 1
task.wait(1)
Cooldown()
end
end
if Team == "Red" then
if RedTeamSpawnCooldown == 0 then
return
else
RedTeamSpawnCooldown -= 1
task.wait(1)
Cooldown()
end
end
end
local function CallSpawn(Team)
if Team == "Blue" then
if BlueTeamSpawnCooldown == 0 then
SpawnSoldier("BlueDummy",Team)
BlueTeamSpawnCooldown = 10
task.wait(1)
Cooldown(Team)
CallSpawn(Team)
end
end
if Team == "Red" then
if RedTeamSpawnCooldown == 0 then
SpawnSoldier("RedDummy",Team)
RedTeamSpawnCooldown = 10
task.wait(1)
Cooldown(Team)
CallSpawn(Team)
end
end
end
CallSpawn("Blue")
CallSpawn("Red")
I did it and same outcome as before so it moves but doesn’t stop when 5 studs away
local function FindTarget(Team, Soldier)
local blockedConnection
local otherTeam
local waypoints
if Team == "Blue" then
otherTeam = "Red"
else
otherTeam = "Blue"
end
for i, soldier in pairs(game.Workspace:FindFirstChild(Team.."Soldiers"):GetChildren()) do
local path = PathfindingService:CreatePath({
AgentCanJump = true
})
local ClosestSoldier = 10000
local AttackSoldier = Instance.new("ObjectValue")
AttackSoldier.Parent = Soldier
AttackSoldier.Name = "AttackSoldier"
for i, soldier in pairs(game.Workspace:FindFirstChild(otherTeam.."Soldiers"):GetChildren()) do
local HumanoidRootPart = soldier:FindFirstChild("HumanoidRootPart")
local value = (Soldier:FindFirstChild("HumanoidRootPart").Position - HumanoidRootPart.Position + Vector3.new(3, 0, 0)).Magnitude
if value < ClosestSoldier then
ClosestSoldier = value
AttackSoldier.Value = HumanoidRootPart
end
end
local success, errormessage = pcall(function()
path:ComputeAsync(Soldier.HumanoidRootPart.Position, AttackSoldier.Value.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
for i, waypoint in pairs(waypoints) do
local humanoid = Soldier:FindFirstChild("Humanoid")
if breakLoop == true then
break
else
humanoid:MoveTo(waypoint.Position)
end
end
end
end
end
local function SpawnSoldier(Type, Team)
local soldier = Soldiers:FindFirstChild(Type):Clone()
soldier.Parent = game.Workspace:FindFirstChild(Team.."Soldiers")
soldier.HumanoidRootPart.CFrame = game.Workspace:FindFirstChild(Team.."Team").CFrame
local team = Instance.new("StringValue")
team.Name = Team
team.Value = Team
local AttackSoldier = soldier:WaitForChild("AttackSoldier")
soldier.Humanoid.MoveToFinished:Connect(function()
local magnitude = (AttackSoldier.Value.Position - soldier.HumanoidRootPart.Position).Magnitude
if magnitude <= 5 then
print("Stopping troop to attack")
Attack(Team, soldier, AttackSoldier.Value)
AttackSoldier:Destroy()
breakLoop = true
else
FindTarget(Team, soldier)
AttackSoldier:Destroy()
end
end)
end
So I changed the breakLoop to become a value inside the soldier which I’ll destroy it when the loop is broken but the same exact things happen of NPCs running into each other then flying. heres script rn
local ServerStorage = game:GetService("ServerStorage")
local PathfindingService = game:GetService("PathfindingService")
local Soldiers = ServerStorage.Soldiers
local BluxMaxTroops = 20
local RedMaxTroops = 10
local BlueTeamSpawnCooldown = 0
local RedTeamSpawnCooldown = 0
local function Attack(Team, Soldier, Enemy)
end
local function FindTarget(Team, Soldier)
local blockedConnection
local otherTeam
local waypoints
if Team == "Blue" then
otherTeam = "Red"
else
otherTeam = "Blue"
end
for i, soldier in pairs(game.Workspace:FindFirstChild(Team.."Soldiers"):GetChildren()) do
local path = PathfindingService:CreatePath({
AgentCanJump = true
})
local ClosestSoldier = 10000
local AttackSoldier = Instance.new("ObjectValue")
AttackSoldier.Parent = Soldier
AttackSoldier.Name = "AttackSoldier"
for i, soldier in pairs(game.Workspace:FindFirstChild(otherTeam.."Soldiers"):GetChildren()) do
local HumanoidRootPart = soldier:FindFirstChild("HumanoidRootPart")
local value = (Soldier:FindFirstChild("HumanoidRootPart").Position - HumanoidRootPart.Position + Vector3.new(3, 0, 0)).Magnitude
if value < ClosestSoldier then
ClosestSoldier = value
AttackSoldier.Value = HumanoidRootPart
end
end
local success, errormessage = pcall(function()
path:ComputeAsync(Soldier.HumanoidRootPart.Position, AttackSoldier.Value.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
if not soldier:FindFirstChild("breakLoop") then
local breakLoop = Instance.new("BoolValue")
breakLoop.Parent = soldier
breakLoop.Name = "breakLoop"
print("Made breakloop for "..soldier.Name)
end
for i, waypoint in pairs(waypoints) do
local humanoid = Soldier:FindFirstChild("Humanoid")
if soldier.breakLoop.Value == true then
break
else
humanoid:MoveTo(waypoint.Position)
end
end
end
end
end
local function SpawnSoldier(Type, Team)
local soldier = Soldiers:FindFirstChild(Type):Clone()
soldier.Parent = game.Workspace:FindFirstChild(Team.."Soldiers")
soldier.HumanoidRootPart.CFrame = game.Workspace:FindFirstChild(Team.."Team").CFrame
local team = Instance.new("StringValue")
team.Name = Team
team.Value = Team
local AttackSoldier = soldier:WaitForChild("AttackSoldier")
soldier.Humanoid.MoveToFinished:Connect(function()
local magnitude = (AttackSoldier.Value.Position - soldier.HumanoidRootPart.Position).Magnitude
print(magnitude)
if magnitude <= 5 then
print("Stopping troop to attack")
Attack(Team, soldier, AttackSoldier.Value)
AttackSoldier:Destroy()
soldier.breakLoop.Value = true
else
FindTarget(Team, soldier)
AttackSoldier:Destroy()
end
end)
end
local function Soldiers(Team)
local soldiers = game.Workspace:FindFirstChild(Team.."Soldiers"):GetChildren()
if #soldiers <= 0 then
return
elseif #soldiers >= 1 then
for i, part in pairs(game.Workspace:FindFirstChild(Team.."Soldiers"):GetChildren()) do
FindTarget(Team, part)
end
task.wait()
Soldiers(Team)
end
end
game.Workspace.BlueSoldiers.ChildAdded:Connect(function()
Soldiers("Blue")
end)
game.Workspace.RedSoldiers.ChildAdded:Connect(function()
Soldiers("Red")
end)
local function Cooldown(Team)
if Team == "Blue" then
if BlueTeamSpawnCooldown == 0 then
return
else
BlueTeamSpawnCooldown -= 1
task.wait(1)
Cooldown()
end
end
if Team == "Red" then
if RedTeamSpawnCooldown == 0 then
return
else
RedTeamSpawnCooldown -= 1
task.wait(1)
Cooldown()
end
end
end
local function CallSpawn(Team)
if Team == "Blue" then
if BlueTeamSpawnCooldown == 0 then
SpawnSoldier("BlueDummy",Team)
BlueTeamSpawnCooldown = 10
task.wait(1)
Cooldown(Team)
CallSpawn(Team)
end
end
if Team == "Red" then
if RedTeamSpawnCooldown == 0 then
SpawnSoldier("RedDummy",Team)
RedTeamSpawnCooldown = 10
task.wait(1)
Cooldown(Team)
CallSpawn(Team)
end
end
end
CallSpawn("Blue")
CallSpawn("Red")
So the issue is that NPCs are colliding with eachother, then flying off into the sky?
If so, I’ve had this issue with NPCs and the way I solved it is to make the NPCs unable to collide with eachother via CollisionGroups
What I would done was have a .stepped connection which checks the current targets magnitude in respect to self. if <=5 then break movement/set walkspeed == 0 however you want to do it, else resume movement.