How can I shorten how many loops I use in this asset loading script?

I made a content loading script for a place in which it loads assets into the place and parents those assets to specified places. The problem I wish to address is how many loops I am using. I am wondering if it’s possible to decrease the amount of in pairs loops I use. The assets are defined in a separate module in the place.

function PreloadAssets() -- used for UI_PC
pcall(function()
	for Index, Child in pairs(GameAssets.SOUNDS) do
		local Sound = Instance.new('Sound')
		Sound.Name = tostring(Index)
		Sound.SoundId = Child
		Sound.Volume = 1		
		if Sound.Name:find('SFX') then
			Sound.Parent = game.SoundService.Sounds.SFX

		elseif Sound.Name:find('Theme') then
			Sound.Parent = game.SoundService.Sounds.Music
		end

		local Asset = { Sound }	
		ContentProvider:PreloadAsync(Asset)
	end
	print('IH4 SOUND ASSETS LOADED')

	for Index, Child in pairs(GameAssets.MAINTEXTURES) do
		local MainImages = Instance.new('ImageLabel')
		MainImages.Name = 'Icon'
		MainImages.SizeConstraint = Enum.SizeConstraint.RelativeYY
		MainImages.Size = UDim2.new(1, 0, 1, 0)
		MainImages.BackgroundTransparency = 0.5
		MainImages.BackgroundColor3 = Color3.fromRGB(25, 25, 25)
		MainImages.BorderColor3 = Color3.fromRGB(255, 255, 255)
		MainImages.Position = UDim2.new(0, -3, 0, 0)
		MainImages.Image = Child		
		MainImages.Parent = ih4.MainMenu.ButtonBin:FindFirstChild(Index)

		local Asset = { MainImages }
		ContentProvider:PreloadAsync(Asset)	
	end
	print('IH4 MENU ICON ASSETS LOADED')

	for Index, Child in pairs(GameAssets.EMBLEMTEXTURE) do
		local ImageLabel = Instance.new('ImageLabel')
		ImageLabel.Name = tostring(Index)
		ImageLabel.Image = Child
		ImageLabel.BackgroundTransparency = 1
		ImageLabel.Size = UDim2.new(0, 200, 0, 200)
		ImageLabel.ImageColor3 = Color3.fromRGB(255, 255, 255)
		ImageLabel.AnchorPoint = Vector2.new(0.5, 0.5)
		ImageLabel.Position = UDim2.new(0.5, 0, 0.4, 0)
		ImageLabel.Parent = Bin
	
		local Asset = { ImageLabel }
		ContentProvider:PreloadAsync(Asset)
	end
	print('LOADING SCREEN EMBLEM LOADED')

	for Index, Child in pairs(GameAssets.BACKCIRCLETEXTURE) do
		local ImageLabel = Instance.new('ImageLabel')
		ImageLabel.Name = tostring(Index)
		ImageLabel.Image = Child
		ImageLabel.BackgroundTransparency = 1
		ImageLabel.Size = UDim2.new(1, 0, 1, 0)
		ImageLabel.ImageColor3 = Color3.fromRGB(20, 20, 20)
		ImageLabel.Position = UDim2.new(0, 0, 0, 0)
		ImageLabel.Parent = ih4.Frames.BackButtonFrame
	
		local Asset = { ImageLabel }
		ContentProvider:PreloadAsync(Asset)
	end
					
	for Index, Child in pairs(GameAssets.BACKTEXTURE) do
		local ImageButton = Instance.new('ImageButton')
		ImageButton.Name = tostring(Index)
		ImageButton.Size = UDim2.new(1, 0, 1, 0)
		ImageButton.ImageColor3 = Color3.fromRGB(255, 255, 255)
		ImageButton.BackgroundTransparency = 1
		ImageButton.Image = Child
		ImageButton.Parent = ih4.Frames.BackButtonFrame.Circle			

		local Asset = { ImageButton }
		ContentProvider:PreloadAsync(Asset)			
	end
end)
end
2 Likes

If you want to avoid the for loops, then create all the asset instances beforehand manually (not through a script) and then write ContentProvider:Preload(parent:GetChildren()). I can’t imagine this would make it significantly faster however (if that is your goal).

Also, why do you put the whole function in a pcall()?

1 Like

The pcall() was used during a test with the script. I just forgot to remove it in the final version of the place.

I’d also probably put all your assets into a single table and then do ContentProvider:Preload() on the one table. Not sure how much (if at all) it improves performance, but I try to reduce the number of lookups and method calls as much as possible.

local Assets = {}

-- inside each for loop
table.insert( Assets, Sound ) -- or ImageLabel, etc.

-- at the end, outside the loops
ContentProvider:PreloadAsync( Assets )

As I say, probably just a personal preference.

1 Like

This is probably obvious, but can I load other sorts of assets, such as Animations, using this method?

Yes, you can preload anything that would usually use an additional web request using this method. That includes unions, meshes, images, sounds, animations, etc.

I’m sure someone will correct me if I’m wrong but I’ve been using it to preload animations in my own game for a few months now and it appears to work as intended.