How come this code doesn't play?

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.

3 Likes

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

1 Like

do you mean like this?

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.

Actually you should only create this Connect Function when the script starts. And not create a new Connection each time it walks to a Waypoint

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")
1 Like

Do it in the SpawnSolider function. Just make sure the script doesnt create multiple Connect Functions for the same Humanoid

1 Like

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

No errors in output

1 Like

Try printing the magnitude out so it will display the distance in output

It never printed is there something wrong with the logic here?

	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()
			breakLoop = true
		else 

Put prints through all functions in the script. And check where they stop printing

1 Like

The logic seems fine to me, must be some other issue

1 Like

Ooh i just realised something, you’re changing the variable breakLoop for the whole script, meaning the Soliders will all breakLoop at the same time.

2 Likes

dang sorry for late response thanks alot once I test this out and if it’s right I’ll give you the solution.

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

1 Like

This will likely help debug whats going on.

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.

2 Likes

Thats a pretty cool way of doing it, Maybe also a Raycast could work

1 Like

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