How do I refer to multiple light/fire objects across several parts at once?

Hi! I’m not a very good scripter at all. I’m trying to create a day/night cycle script that automatically lights torches around the map at 6PM and extinguishes them at 6AM.

I don’t want to have to be editing this code every time I add a new torch so I need a way to locate all the Fire and PointLight objects easily and automatically. I also want it to be as efficient as possible.

Any help is appreciated!

1 Like

You can use a for loop to loop through the children of Lights. Use GetChildren() to get its children.

for i,v in pairs(script.Parent:GetChildren()) do
    local light = v:FindFirstChild("PointLight")
    if light then --make sure the light exists
        --do something with the light
    end
end
3 Likes

You can also use the CollectionService and add a tag to the torches. Then you can do

local Torches = CollectionService:GetTagged("Torch")

where Torches is a table of items with the tag “Torch”

3 Likes
for i,v in pairs(script.Parent:GetDescendants()) do
    if v:IsA(“Fire”) then
        -- code for fire
    elseif v:IsA(“PointLight”) then
        -- code for light
    end 
end
1 Like

Yes but that still requires to iterate through them, where at this point it would probably be better to store them in a table than using CollectionService to retrieve a similar table each time.

It also won’t work for torches that are added dynamically.


You’re pointlessly looping through all descendants when it isn’t needed.

Thanks a lot!
Can anyone explain what is happening here (or link me to relevant wiki pages that explains it):
image

What is i? What is v? What is pairs?

1 Like

If he gives them a tag “Torch” when he adds them it will work dynamically. He can also just store a prefab that’s already tagged and it will still work.

This also gives him an event when it’s added to the workspace.

CollectionService.GetInstanceAddedSignal("Torch"):Connect(function(Torch) 

end)

where the Torch parameter is the torch that was just added.

If he wants to not continuously get this long list he can simply add that to the table of torches that he’s keeping himself.

This is an example of a for loop. i stands for index, it’s the number under which the value v is assigned in the table.
So in this case, i will be an incrementing number, first 1, then 2, etc.
and v will be a direct children of Lights model, such as your Script or a LightBlock.

Read more about loops here

1 Like

Hm, I didn’t know it can work dynamically. Regardless, seeing as the OP is a beginner into roblox lua scripting, a basic and easy to understand solution is preferable here in my opinion.

:eyes: and using the CollectionService which handles a lot of this for him, and is a lot simpler than having to place all his torches under a simple folder. He could just place them around the map willy nilly and let it work on it’s own using the “Collection” of Torches

You are saying that for a beginner like him it’s better to place all his torches into a single folder and do GetDescendants instead of GetChildren to turn his Torches on at a specific time?

Instead of you know… Just doing

for i,v in ipairs(Torches) do
  if v:IsA("Fire") then
    -- code for fire
  elseif v:IsA("PointLight") then
    -- code for light
  end
end

I don’t mind the extra leg work. I’m new to scripting but I’ve been using studio for 10 years now so no biggie

What’s going wrong here?

Let us not get too carried away. There are multiple ways to achieve what the OP is asking and we should not just limit it to one method. We all have our personal ways on coding so please be open minded to other ways.

1 Like

Your first line is not complete. The variable was not declared properly

Oh right of course, I don’t need it anymore ehehe thanks

There’s a Plugin for the CollectionService called Tag Editor

It would make this job a lot simpler if you’d like to use it in the future. Just select the torch model itself, and apply a tag named whatever you want.

You can then use this API

To get all models in the entire place with that tag.

To do it use a for loop. In the next example, I made a function to toggle the lights every time you press a button.

local Lights = {} -- Empty table to store our lights
local AreLightsOn = true -- Boolean Value to check if our lights are on/off

for _, v in pairs(game.Workspace.Lights:GetChildren()) do -- This for loop will get the Childrens of Folder Lights
	if v.Name == "Light" then -- If Children's name is "Light" then it will insert in the table Lights
		table.insert(Lights,v)
	end
end

function ToggleLights() -- This function will toggle the lights. Run it and the lights will automatically turn on/off.
	if AreLightsOn == false then
		for _, v in pairs(Lights) do
			v.SurfaceLight.Enabled = true
			v.Material = Enum.Material.Neon
		end
		script.Parent.BrickColor = BrickColor.new("Lime green")
		AreLightsOn = true
	else
		for _, v in pairs(Lights) do
			v.SurfaceLight.Enabled = false
			v.Material = Enum.Material.Glass
		end
		script.Parent.BrickColor = BrickColor.new("Really red")
		AreLightsOn = false
	end
end

script.Parent.ClickDetector.MouseClick:Connect(ToggleLights) -- It will run the function ToggleLights() when the Part is clicked.

Here are the Models that I used:
Lights.rbxm (4.3 KB)

You should add some checks to your function. For example, to check if the Lights has a Children, SurfaceLight / PointLight / SpotLight.

3 Likes