Hello! I’m trying to make a capture the flag game, and I’m trying to test touching the flag stands. The problem is that the Touched event doesn’t fire at all, with no errors popping up in the output. The position of the flag stands do print, proving that I got them. The flag stands are inside of the maps, in replicated storage, and aren’t in the workspace until they are cloned.
I’ve tried making the variables global, moving the function out of the while loop, and trying to place the variables outside of the function, but WaitForChild doesn’t have an option to make it recursive.
local Lobby = workspace.Lobby
local Maps = game.ReplicatedStorage.Maps:GetChildren()
local Status = game.ReplicatedStorage.Status
local Teams = {game.Teams.Red, game.Teams.Blue}
local intermissionTime = 5
local roundTime = 180
while true do
-- Intermission
for i = intermissionTime, 0, -1 do
Status.Value = "Intermisson: "..i
task.wait(1)
end
-- Spawn Random map
local chosenMap = Maps[math.random(1, #Maps)]
local clonedMap = chosenMap:clone()
clonedMap.Parent = workspace
Status.Value = "Map: "..clonedMap.Name
task.wait(3)
local BlueFlagStand = game.Workspace:FindFirstChild("BlueFlaStand", true)
local RedFlagStand = game.Workspace:FindFirstChild("RedFlagStand", true)
print(RedFlagStand.Position)
-- Assign teams
for i, player in pairs(game.Players:GetPlayers()) do
if player then
local randomTeam = Teams[math.random(1, #Teams)]
player.Team = randomTeam
player:LoadCharacter()
end
end
-- Game timer
for i = roundTime, 0, -1 do
Status.Value = "Game: ".. i
task.wait(1)
end
RedFlagStand.Touched:Connect(function(hit)
print(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local char = hit.Parent
print("Touched")
end
end)
-- Spawm players back into the lobby
for i, players in pairs(game.Players:GetPlayers()) do
if players then
players.Team = game.Teams.Waiting
players:LoadCharacter()
end
end
clonedMap:Destroy()
end
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.
Make sure that the names you’re using to find the flag stands are correct. In your code, you’re looking for flag stands named “BlueFlaStand” and “RedFlagStand”. There seems to be a typo in “BlueFlaStand”.
Then it might be something with event connection timing; the event connection for the Touched event is being set up inside the loop where you’re iterating through the maps and managing the game flow. This means that you’re creating a new event listener each time you go through the loop. This could potentially lead to multiple listeners being attached, causing unexpected behavior.
Here’s an example of how you can modify your code to address these issues:
-- Other code above remains the same
local BlueFlagStand = game.Workspace:WaitForChild("BlueFlagStand")
local RedFlagStand = game.Workspace:WaitForChild("RedFlagStand")
RedFlagStand.Touched:Connect(function(hit)
local character = hit.Parent
local player = game.Players:GetPlayerFromCharacter(character)
if player then
print(player.Name .. " touched the Red flag stand!")
end
end)
-- Start the game loop
while true do
-- Rest of your game loop logic
-- Inside the loop, you can update the positions of the flag stands if they are dynamically changing
-- Rest of your game loop logic
end
I used WaitForChild instead of FindFirstChild to ensure that the script waits until the flag stands are available in the workspace. Also, I’ve moved the event connection outside of the loop to ensure that only one event listener is attached for each flag stand.
this is where the problem most likely is. You are using a for loop before the touched event is connected, and this game timer loop is yielding the rest of the script. A solution would be to put that part in a coroutine.
local timer=coroutine.create(function()
for i = roundTime, 0, -1 do
Status.Value = "Game: ".. i
task.wait(1)
end
end)
coroutine.resume(timer)
you can then later stop the timer with coroutine.close or pause with coroutine.yield
edit: I realized this can cause your game to crash since all of the code is in a while loop, and when removing that for loop it never yields. So you’ll need some sort of way to know when the game is being played and when its over, this is to stop the game from repeat everything before the round is over.
You could also move the for loop to after you connect the touched events but before you start the round ended part
I forgot WaitForChild doesn’t have a built-in option for recursive searching. In this case, you can implement your own recursive function to wait for the flag stands to appear in the workspace.
Here’s an example:
-- Recursive function to wait for a child to appear
local function WaitForChildRecursive(parent, childName)
local child = parent:FindFirstChild(childName)
if child then
return child
else
local connection
local promise = Instance.new("BindableEvent")
connection = parent.ChildAdded:Connect(function(childAdded)
if childAdded.Name == childName then
connection:Disconnect()
promise:Fire(childAdded)
end
end)
local result = promise.Event:Wait()
promise:Destroy()
return result
end
end
-- Wait for the flag stands to appear
local BlueFlagStand = WaitForChildRecursive(game.Workspace, "BlueFlagStand")
local RedFlagStand = WaitForChildRecursive(game.Workspace, "RedFlagStand")
if not BlueFlagStand or not RedFlagStand then
error("Flag stands not found!")
end
-- Rest of your script remains the same
This code defines a WaitForChildRecursive function that will wait for a child with the specified name to appear in a parent. It uses a BindableEvent and a connection to the ChildAdded event to wait for the child to be added if it doesn’t exist initially. I’m not sure if this will work, but you can try.
If the while loop doesn’t run unless you place the WaitForChildRecursive function below it, it might be due to the fact that the flag stands are not being found in the workspace, causing the script to get stuck in the waiting loop.
you can add some debugging output to better understand what’s happening.
-- Recursive function to wait for a child to appear
local function WaitForChildRecursive(parent, childName)
local child = parent:FindFirstChild(childName)
if child then
return child
else
local connection
local promise = Instance.new("BindableEvent")
connection = parent.ChildAdded:Connect(function(childAdded)
if childAdded.Name == childName then
connection:Disconnect()
promise:Fire(childAdded)
end
end)
local result = promise.Event:Wait()
promise:Destroy()
return result
end
end
-- Wait for the flag stands to appear
local BlueFlagStand = WaitForChildRecursive(game.Workspace, "BlueFlagStand")
print("BlueFlagStand found")
local RedFlagStand = WaitForChildRecursive(game.Workspace, "RedFlagStand")
print("RedFlagStand found")
if not BlueFlagStand or not RedFlagStand then
error("Flag stands not found!")
end
-- Rest of your script
You should be able to see in the console whether the script successfully finds the flag stands or if it’s getting stuck in the waiting loop. If you see the “BlueFlagStand found” and “RedFlagStand found” messages, it means the script found the flag stands, and the issue may lie elsewhere in your script. If you don’t see these messages, it means the script is still waiting for the flag stands to appear. Maybe try checking if the flag names match the names in the script and model of the flags in your game; other than that, idk.
I tried doing this in a separate script, to no success
-- Recursive function to wait for a child to appear
local function WaitForChildRecursive(parent, childName)
local child = parent:FindFirstChild(childName)
if child then
return child
else
local connection
local promise = Instance.new("BindableEvent")
connection = parent.ChildAdded:Connect(function(childAdded)
if childAdded.Name == childName then
connection:Disconnect()
promise:Fire(childAdded)
end
end)
local result = promise.Event:Wait()
promise:Destroy()
return result
end
end
-- Wait for the flag stands to appear
local BlueFlagStand = WaitForChildRecursive(game.Workspace, "BlueFlagStand")
print("BlueFlagStand found")
local RedFlagStand = WaitForChildRecursive(game.Workspace, "RedFlagStand")
print("RedFlagStand found")
if not BlueFlagStand or not RedFlagStand then
error("Flag stands not found!")
end
RedFlagStand.Touched:Connect(function(hit)
print(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local char = hit.Parent
print("Touched")
end
end)
wait wait wait wait wait actually isn’t the issue just that you initiate the game timer BEFORE you connect the touched events? shouldn’t you connect the events first? otherwise you need to wait for the game to end before the flags would work
just swap the order of the Game timer and the events