Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Soundregions with 2 parts of the same name. How do i make this work?

I have a sound region script that detects if you are inside a parts region.

If you leave the area the music stops, if you walk into another parts region it starts another. and if the 2 parts overlap at any point, and you stand in the overlap, both audio plays at the same time. But if you have 2 parts of the same name, for 1 single audio, that audio doesnt play.

https://imgur.com/AIwdQr8


local SoundService = game:WaitForChild("SoundService")

local SoundRegionsWorkspace = game.Workspace:WaitForChild("SoundRegion")

local found = false

while wait(1) do
	for i, v in pairs (SoundRegionsWorkspace:GetChildren()) do
		found = false
		local region = Region3.new(v.Position - (v.Size/2),v.Position + (v.Size/2))
		local parts = game.Workspace:FindPartsInRegion3WithWhiteList(region, game.Players.LocalPlayer.Character:GetDescendants())
		
		for _, part in pairs(parts) do
			if part:FindFirstAncestor(game.Players.LocalPlayer.Name)then
				found = true
				break
			else
				found = false
			end
		end
		
		if found == true then
			if script.Parent.SoundRegions[v.Name].IsPlaying == false then
				script.Parent.SoundRegions[v.Name]:Play()
				break
			end	
		else
			script.Parent.SoundRegions[v.Name]:Stop()			
		end
	end
end

I believe that whats happening is if your standing in 1 of the parts and not the other, its seeing it as true and false at the same time. and it starts and ends it at the same time. there is no error in the output, i've worked on it for 2 days and im still unsure how to structure it correctly so it can play the music if there are 2 parts of the same name

1 answer

✓ Accepted answer

Improvements

Use GetService() for Roblox services rather than WaitForChild()

Make a local variable for instances which are used multiple times

Use workspace instead of game.Workspace

I prefer placing the wait() inside the loop than in the while // do as it's cleaner

RenderStepped works on every frame and only on the client so its preferred for audio changes to happen ASAP

Issues

I changed the "found" to be a table for the audio that is supposed to play so that it can be changed based on the name and not every part connected to the audio.

Switching the positions of the region and audiofolder allowed the table to run through each audio once, and the value was only changed for true as the false value was set as a default before the table was run

Revised Local Script

local player = game:GetService("Players").LocalPlayer
local SoundService = game:GetService("SoundService")
local SoundRegionsWorkspace = workspace:WaitForChild("SoundRegion")

local startgui = script.Parent
local afolder = startgui:WaitForChild("SoundRegions")
local found = {}

for aindex, aval in pairs(afolder:GetChildren()) do
	found[aval.Name] = false
end

game:GetService("RunService").RenderStepped:Connect(function()
	if player.Character then
		for findex, fval in pairs(afolder:GetChildren()) do
			found[fval.Name] = false
		end
		
		for mindex, audio in pairs(afolder:GetChildren()) do
			for rindex, child in pairs(SoundRegionsWorkspace:GetChildren()) do
				local region = Region3.new(child.Position - (child.Size / 2), child.Position + (child.Size / 2))
				local desc = workspace:FindPartsInRegion3WithWhiteList(region, player.Character:GetDescendants(), 20)
				
				for rpart, part in pairs(desc) do
					if part:FindFirstAncestor(player.Name)then
						found[child.Name] = true
					end
				end
				
				if found[child.Name] == true and audio.Name == child.Name and audio.IsPlaying == false then
					audio:Play()
				elseif found[child.Name] == false and audio.Name == child.Name and audio.IsPlaying == true then
					audio:Stop()
				end
			end
		end
	end
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.