Is this an efficient way to change multiple images when one image changes?

I’m currently attempting to make a script on the client that will change a bunch of images to match one image if it changes.

Essentially: TV’s decal, or Video changes, any clones will change alongside it.

I currently have it check the descendants every time to find any images that could have been added to the Workspace since the games start.

local Titantrons = {}
for i,v in pairs(script.ScreenValues:GetChildren()) do
	repeat task.wait() until game.Workspace:FindFirstChild(v.Value)
	if game.Workspace:FindFirstChild(v.Value) then
		Titantrons[v.Value.." Image Changer"] = game.Workspace[v.Value].Decal.Changed:Connect(function(ValueChanged)
			if ValueChanged == "ChangedTexture" or ValueChanged == "Texture" then
				local id = string.split(game.Workspace[v.Value].Decal.Texture,"http://www.roblox.com/asset/?id=")[2] or string.split(game.Workspace[v.Value].Decal.Texture,"rbxassetid://")[2] or game.Workspace[v.Value].Decal.Texture
				local Stages = game.Workspace:FindFirstChild("Stages") or game.Workspace
				for index,Item in pairs (Stages:GetDescendants()) do
					if Item:IsA("BasePart") and string.lower(Item.Name) == (string.lower(v.Value).."copy") then
						if Item:FindFirstChild("Decal") then
							Item.Decal.Texture = "http://www.roblox.com/asset/?id="..id
						elseif Item:FindFirstChild("SurfaceGui") and Item.SurfaceGui:FindFirstChild("ImageLabel") then
							Item.SurfaceGui.ImageLabel.Image = "rbxassetid://"..id
						end
					end
				end
			end
		end)
		Titantrons[v.Value.." Video Changer"] = game.Workspace[v.Value].SurfaceGui.VideoFrame.Changed:Connect(function(ValueChanged)
			if ValueChanged == "Video" then
				local id = string.split(game.Workspace[v.Value].SurfaceGui.VideoFrame.Video,"http://www.roblox.com/asset/?id=")[2] or string.split(game.Workspace[v.Value].SurfaceGui.VideoFrame.Video,"rbxassetid://")[2] or game.Workspace[v.Value].SurfaceGui.VideoFrame.Video
				local Stages = game.Workspace:FindFirstChild("Stages") or game.Workspace
				for index,Item in pairs (Stages:GetDescendants()) do
					if Item:IsA("BasePart") and string.lower(Item.Name) == (string.lower(v.Value).."copy") then
						if Item:FindFirstChild("SurfaceGui") and Item.SurfaceGui:FindFirstChild("VideoFrame") then
							Item.SurfaceGui.VideoFrame.Looped = game.Workspace[v.Value].SurfaceGui.VideoFrame.Looped;
							Item.SurfaceGui.VideoFrame.Video = "rbxassetid://"..id
						end
					end
				end
			else
				local Stages = game.Workspace:FindFirstChild("Stages") or game.Workspace
				for index,Item in pairs (Stages:GetDescendants()) do
					if Item:IsA("BasePart") and string.lower(Item.Name) == (string.lower(v.Value).."copy") then
						if Item:FindFirstChild("SurfaceGui") and Item.SurfaceGui:FindFirstChild("VideoFrame") then
							if ValueChanged == "Volume" then
								Item.SurfaceGui.VideoFrame.Volume = game.Workspace[v.Value].SurfaceGui.VideoFrame.Volume
							elseif ValueChanged == "Playing" then
								Item.SurfaceGui.VideoFrame.Playing = game.Workspace[v.Value].SurfaceGui.VideoFrame.Playing
							end
						end
					end
				end
			end
		end)
	end
end

In terms of efficiency, rather than checking each descendant for images whenever the image changes, you could keep a running table:

local Images = {}
workspace.DescendantAdded:Connect(function(Item)
    if Item matches then
        table.insert(Images, Item)
    end
end)
for i, Item in ipairs(workspace:GetDescendants()) do
    if Item matches then
        table.insert(Images, Item)
    end
end
1 Like

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