How to detect if at least one boolvalue is true among multiple models in a folder

  1. What do you want to achieve?
    I want to try and detect if at least one enemy in a folder has a boolvalue called “Attacking” enabled. Afterwards the current ambience will stop, and a battle ambience will play. If all the values are false or none can be found(due to all enemies being destroyed), then the normal ambience returns.

  2. What is the issue?
    It doesn’t detect any boolvalues, and doesn’t play the necessary audio. There are no errors in the output. (Edit: Most of these issues have been fixed. The only remaining issue is that it only gets the value of the first enemy instead of looping through all the enemies’ values.)

  3. What solutions have you tried so far?
    I’ve seen almost similar topics of getting boolvalues in pairs, and have attempted to try them, but I’m struggling to grasp, and implement the concept.

This is the updated script after looking through the solutions:

local EnemyFolder = workspace.Attackables
local Ambience = script.AmbienceLente
local BattleMusic = script.VengefulAttack
local ActiveSong = nil
local DeactiveSong = nil

while true do
	wait(0.1)
	local Enemies = EnemyFolder:GetChildren()
	if (#Enemies > 0) then
		for i, v in pairs (Enemies) do			
			if v:IsA("Model") and v.Attacking.Value == true then
				ActiveSong = BattleMusic
				DeactiveSong = Ambience
			elseif not v:IsA("Model") or v.Attacking.Value == false then
				ActiveSong = Ambience
				DeactiveSong = BattleMusic
			end
		end		
	else
		ActiveSong = Ambience
		DeactiveSong = BattleMusic		
	end
	if DeactiveSong.IsPlaying then
		DeactiveSong:Stop()
	end
	if ActiveSong.IsPaused then
		ActiveSong:Play()
	end
end
1 Like
for i, v in pairs(Enemies) do
		if v:IsA("Model") and v.Attacking.Value then
			ActiveSong = BattleMusic
			DeactiveSong = Ambience
            break
		elseif not v:IsA("Model") or not v.Attacking.Value then
			ActiveSong = Ambience
			DeactiveSong = BattleMusic
		end	
	end

The battle audio plays now, but it sounds as if its constantly being paused/played, and still continues even if there are no enemies left.

Replace wait(0.1) with.

ActiveSong:Play()
ActiveSong.Ended:Wait()

https://developer.roblox.com/en-us/api-reference/event/Sound/Ended

This won’t work, as the audios are looped, but I was able to stop the constant stopping/playing by adding if statements:

if DeactiveSong.IsPlaying then
		DeactiveSong:Stop()
end
if ActiveSong.IsPaused then
	ActiveSong:Play()
end

I have found two issues now;

  1. If all enemies are destroyed it won’t change the audio (Tried adding enemies == nil, but no results).

  2. It only detects the value for the first enemy in the folder, but not for all enemies at once.

Did you try if (#enemies > 0) then? The # operator will get the length of a table

1 Like

Thanks, the audios were able to switch, the only issue still is that it only detects the value of the first model in the folder, even if other enemies are attacking.

This won’t work, as the audios are looped

Seems like a poor design choice, loop/unloop sound instances as they are played/stopped respectively.

I unlooped the audios, and replaced wait(0.1) with,

ActiveSong:Play()
ActiveSong.Ended:Wait()

but it prevented the while true loop from looping through the enemy folder, and switching the audios until the active song was finished.

local EnemyFolder = workspace.Attackables
local Ambience = script.AmbienceLente
local BattleMusic = script.VengefulAttack
Ambience.Loop = true
BattleMusic.Loop = true
local ActiveSong = nil
local DeactiveSong = nil

while true do
local Enemies = EnemyFolder:GetChildren()
local canplay = false
for i, v in pairs(Enemies) do
if v:IsA(“Model”) and v.Attacking.Value then
– ActiveSong = BattleMusic
canplay = true
– DeactiveSong = Ambience
elseif not v:IsA(“Model”) or not v.Attacking.Value then
–ActiveSong = Ambience
–DeactiveSong = BattleMusic
end
end
Ambience.Playing = not canplay
BattleMusic.Playing = canplay
–DeactiveSong:Stop()
–ActiveSong:Play()
wait(0.1)
end

Don’t forget to make the sound loops

The sounds didn’t play when the attacking value was false, and the sounds were constantly playing and stopping.

I was able to prevent the sounds from stopping/playing, switch when there are no enemies, and switch when the attacking value is false. This is the updated script:

local EnemyFolder = workspace.Attackables
local Ambience = script.AmbienceLente
local BattleMusic = script.VengefulAttack
local ActiveSong = nil
local DeactiveSong = nil

while true do
	wait(0.1)
	local Enemies = EnemyFolder:GetChildren()
	if (#Enemies > 0) then
		for i, v in pairs (Enemies) do			
			if v:IsA("Model") and v.Attacking.Value then
				ActiveSong = BattleMusic
				DeactiveSong = Ambience
			elseif not v:IsA("Model") or not v.Attacking.Value then
				ActiveSong = Ambience
				DeactiveSong = BattleMusic
			end
		end		
	else
		ActiveSong = Ambience
		DeactiveSong = BattleMusic		
	end
	if DeactiveSong.IsPlaying then
		DeactiveSong:Stop()
	end
	if ActiveSong.IsPaused then
		ActiveSong:Play()
	end
end

The only remaining issue is that it only gets the attacking value of the first enemy in the folder, instead of looping through the attack values of all the enemies.

local EnemyFolder = workspace.Attackables
local Ambience = script.AmbienceLente
local BattleMusic = script.VengefulAttack

while true do
    task.wait(0.1)
	local Enemies = EnemyFolder:GetChildren()
	local EnemyAttacking=false
	for i, v in pairs(Enemies) do
		if v:IsA("Model") and v.Attacking.Value then
			EnemyAttacking=true
			break
		end
	end
	
	if EnemyAttacking then
		if Ambience.IsPlaying() then Ambience.Stop() end
		if not BattleMusic.IsPlaying() then BattleMusic.Play() end
	else
		if BattleMusic.IsPlaying() then BattleMusic.Stop() end
		if not Ambience.IsPlaying() then Ambience.Play() end
	end	

end

Keeps giving an error “Attempt to call a boolean value”.

She made a mistake, this should work.

local Ambience = script.AmbienceLente
local BattleMusic = script.VengefulAttack

while true do
    task.wait(0.1)

    local Enemies = EnemyFolder:GetChildren()
    local EnemyAttacking=false

    for i, v in pairs(Enemies) do
        if v:IsA("Model") and v.Attacking.Value then
            EnemyAttacking=true
            break
        end
    end

    if EnemyAttacking then
        if Ambience.IsPlaying then Ambience:Stop() end
        if not BattleMusic.IsPlaying then BattleMusic:Play() end
    else
        if BattleMusic.IsPlaying then BattleMusic:Stop() end
        if not Ambience.IsPlaying then Ambience:Play() end
    end
end
1 Like

Ahh yeah, my bad .IsPlaying() should be just .IsPlaying

1 Like

You forgot to add local EnemyFolder = workspace.Attackables, but other than that, everything is working perfectly. Thanks everyone for all your help.

1 Like