Table is not indexing correctly

I am trying to make a system where the sounds in each folder changes depending on a variable from 0-1 (“volume”).

The issue is that when the sounds in the [t] table are set in the 3rd loop, they’re all set to 1 specific volume.

I have tried a lot of different things, but to no improvements. One of the things I tried was to set y.Volume = v to instead be y.Volume = r[y], which just leads to nothing happening.
Volume.Value is defined from somewhere else in the script, and I printed to make sure it is correct so you don’t have to worry about that variable.

local t = game.SoundService.sounds:GetDescendants()
local r = {}

for i,v in pairs(t) do
	if v:IsA("Sound") then
		r[v] = v.Volume
	end
end

volume.Changed:Connect(function()
	
	for i,v in pairs(r) do
		v = v * volume.Value
	
		for x,y in pairs(t) do
			if y:IsA("Sound") then
				y.Volume = v
				
			end
		end
	end
end)

Hi there,

The main caveat here with your 2nd pairs(r) loop and 3rd pairs(t) loop is that the 2nd loop begins it’s first iteration, overrides the value of v and lets the 3rd loop run each iteration before the 2nd loop begins it’s next iteration. Hence the 3rd loop fully runs it’s course upon each iteration of the second loop, and what you’re left with in the end is the value of v in the last iteration of the 2nd loop.

If I understood what you’re trying to achieve correctly, give the below code a shot and see if it’s getting you where you want to be:

local t = game.SoundService:WaitForChild("sounds"):GetDescendants()
local r = {}

for i,v in pairs(t) do
	if v:IsA("Sound") then
		r[v] = v.Volume
	end
end

volume.Changed:Connect(function()
	for x,y in pairs(t) do
		if y:IsA("Sound") then
			y.Volume = r[y] * volume.Value
		end
	end
end)
1 Like

yes that works :smiley:

I do also understand why it works and what the issue was, although I don’t think I understand the r[y] and r[v] properly. Could you explain it if you don’t mind?

Hi there,

Glad to hear that sorted it for ya. And absolutely!

Let’s divide it into sections:

for i,v in pairs(t) do
	if v:IsA("Sound") then
		r[v] = v.Volume
	end
end

Above is the initial for loop that you had already created to populate your r = {} dictionary.

r[v] = v.Volume

Here, what you’re essentially doing is you’re setting the index of the dictionary to the Sound Object, and setting that index’s value to the sound.Volume of the Sound Object.
This is an example of what your live r dictionary would look like with a single element present.

local r = {
	[Instance(1111ABC234)] = volumeValue,
	
}

When you store an object to programmatical entity such as a table, the object is inserted in the form of it’s memory reference as a path to the object, not exactly the object instance itself. This memory reference doesn’t change as long as the Object isn’t destroyed. That’s what the Instance(1111ABC234) is in the table index of r.

Moving on:

volume.Changed:Connect(function()
	for x,y in pairs(t) do
		if y:IsA("Sound") then
			y.Volume = r[y] * volume.Value
		end
	end
end)

Now that you have a consistent “path” to the object stored in your dictionary, instead of nesting multiple for loops to fetch the object and it’s properties, you simply get that object from your table t which also already contains the same Instances and directly query it using r[y], because r[y] is the same as r[v] that we previously set in the first setup for loop. Hence, this way you can easily query the exact instance in both tables through a singular loop and modify it’s value directly according to whatever other parameters it may be manipulated with, such as the volume.Volume here.

You’re simply getting the same Instance through 2 different dictionaries, one stores it with it’s memory reference and a property, while the other is simply an array carrying all objects.

I hope I didn’t explain it in a way that complicates things even more for you, and I apologize in advance if I did. :sweat_smile:

If you have any other questions, please don’t hesitate to ask. Good luck with your project.

1 Like

So how I understand it now: It is multiplying the y values inside of r with volume.Value.

If you were to do r[x], would it then try to multiply the instance with the volume.Value, creating an error?

Correct, well, this is assuming you understand that the y in r[y] is an element of table t, which happens to the Sound object that we stored earlier as you can see in the below loop:

for x,y in pairs(t) do
	if y:IsA("Sound") then
		y.Volume = r[y] * volume.Value
	end
end

The same loop can be rewritten as:

for index, sound in pairs(t) do
	if sound:IsA("Sound") then
		sound.Volume = r[sound] * volume.Value
	end
end

In programming, this is why it can be incredibly helpful to name variables appropriately and meaningfully instead of single alphabets, because in more complicated or lengthier codes, it becomes crucial you can clearly understand exactly what variable means what.

And that’s half true. Yes you would run into an error, but not for trying to multiply an Instance with a number, because r[x] wouldn’t be an Instance, it would be nil. Why? Because r[x] would return nil since x is an integer (in table t), not an object and we already replaced all direct indices of the r table with sound instances originally, hence you can no longer call a value from the r table directly through an index number, such as r[3].

Here, let me simplify. For example, if you have a table Table:

local Table = {
	"A",
	"B",
	"C"
	
}

This table is the exact same table as:

local Table = {
	[1] = "A",
	[2] = "B",
	[3] = "C"
	
}

So if you were to get the second index of the Table using print(Table[2]), it will return "B".

Now, let’s rewrite the same table but with different indices.

local Table = {
	["X"] = "A",
	["Y"] = "B",
	["C"] = "C"
	
}

Now if you try to call the same print(Table[2]), it’ll return nil instead of "B" because we’ve overwritten the defaultly generated index values with characters, or strings.

This is exactly what we did with your code but instead of strings, it’s objects.

I hope that makes more sense. Cheers.

1 Like

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