Find all GameObjects in a scene by Tag and access the audio source on them.

Hi Im using this code to try and find all the game objects in a scene with tag and then tell them to Play() the audio source that is attached to them, but it only finds one object and plays that one. I want to have many of the same objects in a scene and have them play there audio source attached to them. The audio source is a child game object to a game object which has a Tag.

public class findObjects : MonoBehaviour
{
    public AudioSource[] aSource;



    void Start()

    {
        aSource = GameObject.FindGameObjectWithTag("SoundSpots").GetComponentsInChildren<AudioSource>();
    }

   
    // Update is called once per frame
    void Update ()
    {
        foreach(AudioSource aS in aSource)
        {
            aS.Play();
        }
   
    }
}

It looks like FindGameObjectWithTag is an old method and doesnt exist in the script reference anymore.

You really want FindGameObjectsWithTag to fill an array.

Unrelated: aS is highlighted as a keyword “as”, so while it did work its probably a good idea to not use aS.

Yes sorry, Im a bit of a newb when it comes to that, Im not sure how to get my AudioSource after FindGameObjectsWithTag(“SoundSpots”) ???

using UnityEngine;
using System.Collections;

public class findObjects : MonoBehaviour
{
    public AudioSource[] aSource;



    void Start()

    {
        aSource = GameObject.FindGameObjectsWithTag("SoundSpots").  ??????????
    }

   
    // Update is called once per frame
    void Update ()
    {
        foreach(AudioSource aS in aSource)
        {
            aS.Play();
        }
   
    }
}

you will have to loop over the objects to get the AudioSource Component of each object, and save that into a new list.

you could do something like this

using UnityEngine;

public class FindSoundSpots : MonoBehaviour {
    private AudioSource[] _audioSources;

    private void Start () {
        var temp = GameObject.FindGameObjectsWithTag("SoundSpots");
        _audioSources = new AudioSource[temp.Length];

        for (int i = 0; i < _audioSources.Length; i++) {
            _audioSources[i] = temp[i].GetComponent<AudioSource>();
        }
    }
}

or if you really want a one liner you could do something like this

using System.Linq;
using UnityEngine;

public class FindSoundSpots : MonoBehaviour {
    private AudioSource[] _audioSources;

    private void Start () {
        _audioSources = GameObject.FindGameObjectsWithTag("SoundSpots").Select(x => x.GetComponent<AudioSource>()).ToArray();
    }
}

not sure what you are trying to do, but in your code sample you are trying to call Play on the audio sources every frame thus restarting the audio every frame.

Awesome thanks !'ll test it out and see how it works.

I was just playing around with your code, where would I actually put _audioSources.Play(); ?
Sorry for another nube question.

would depend on what you are trying to do and when you want them to play

Well what happens is I have all these pipes that are set up in my scene and they are connected to a main wind turbine that sends rushing air throught them, so I have sound spots set along the areas of the pipe, but sometimes the pipes can be changed around so the sound spots have to change too. Anyway so then when the scene is playing your controlled character can go up to the turbine machine and switch it on so then that switches all the sound spots on and you can turn them all off as well so in my code I just have a function for off and a function for on like this.

using UnityEngine;

public class FindSoundSpots : MonoBehaviour
{
    private AudioSource[] _audioSources;

    private void Start()
    {
        var temp = GameObject.FindGameObjectsWithTag("SoundSpots");
        _audioSources = new AudioSource[temp.Length];

        for (int i = 0; i < _audioSources.Length; i++)
        {
            _audioSources[i] = temp[i].GetComponent<AudioSource>();
        }
    }



    public void TurnOn()
    {
       // _audioSources.PLay  ...but this doesnt seem to work ??
      
        //Do you need to do like a    foreach(AudioSource aSource in _audioSources)
        //  {   aSource.Play();    }   but that doesnt seem to work either
    }

    public void TurnOff()
    {

    }
}

you cant do _audioSources.Play() since _audioSources is a array, you would have to loop the array and call Play on each audiosource in it. After that it should work once you call TurnOn(). Just remember anytime you are working with a array or list, you will have to loop over it to work with its contents.

i read your OP a 2nd time, and i realize i missed the part where you said the AudioSources were children of the objects with the SoundSpots tag.

so switch

_audioSources[i] = temp[i].GetComponent<AudioSource>();

with

_audioSources[i] = temp[i].GetComponentInChildren<AudioSource>();

Thanks very much passerbymc, this now works great!, thanks so much for your time and help, Im very great full. In the end this is what worked

    private AudioSource[] _audioSources;

    public void TurnOn()
    {
        var temp = GameObject.FindGameObjectsWithTag("SoundSpot");
        _audioSources = new AudioSource[temp.Length];
        for (int i = 0; i < _audioSources.Length; i++)
        {
            _audioSources[i] = temp[i].GetComponentInChildren<AudioSource>();
            _audioSources[i].Play();
            Debug.Log("all audio sources are on");
        }
    }

    public void TurnOff()
    {
        var temp = GameObject.FindGameObjectsWithTag("SoundSpot");
        _audioSources = new AudioSource[temp.Length];

        for (int i = 0; i < _audioSources.Length; i++)
        {
            _audioSources[i] = temp[i].GetComponentInChildren<AudioSource>();
            _audioSources[i].Stop();
            Debug.Log("all audio sources are off");

        }
    }

glad that worked for you. Since both FindGameObjectsWithTag and GetComponent are pretty expensive operations to call you might want to take a approach more similar to this.

using UnityEngine;

public class FindSoundSpots : MonoBehaviour {
    private AudioSource[] _audioSources;

    private void Start() {
        var temp = GameObject.FindGameObjectsWithTag("Soundspot");
        _audioSources = new AudioSource[temp.Length];
        for (int i = 0; i < _audioSources.Length; i++) {
            _audioSources[i] = temp[i].GetComponentInChildren<AudioSource>();
        }
    }

    public void TurnOn() {
        foreach (var audioSource in _audioSources) {
            audioSource.Play();
        }
    }

    public void TurnOff() {
        foreach (var audioSource in _audioSources) {
            audioSource.Stop();
        }
    }
}

this way the array of audio sources is only made once, and thus FindObjectWithTag and GetComponent only ever get called in your startup method. Than you TurnOn and TurnOff methods simply just loop over the existing collection and play or stop.

OK I see, yes that makes much more sense. Thanks you.

So my problem is now is that If I have different networks of Fan pipe systems, I need to be able to have some certain sounds turned off from one gameobject and have a different lot of sound sources turn off from a different object. I have tried giving each sound(gameobject) an i.d number and each Fan(gameobject) and id number but I think my logic is a bit stupid because either Fan object just turns all the sounds on or off

using UnityEngine;
using System.Collections;

public class AuxiliaryFan : MonoBehaviour
{
    private const string AuxFanSound = "AuxFanSound";
    private const string Attribute_FanIDNumber = "FanIDNumber";
    public AudioSource auxFanSound;
    //private GameObject[] simAudio;
    private AudioSource[] audio;

    public float FanIDNumber;
    private AuxPipeSound[] auxPipeSound;

    private int on_off;

    private void Start()
    {
        SimObject simOBject = transform.parent.GetComponent<SimObject>();
        simOBject.AddAttributeWatcher(UpdateSound);

    }

    private void OnDisable()
    {
        SimObject simObject = transform.parent.GetComponent<SimObject>();
        if (simObject) simObject.RemoveAttributeWatcher(UpdateSound);
    }

    private void UpdateSound(SimObject simObject)
    {
        SimObject.BoolAttribute isActive = (SimObject.BoolAttribute)simObject.GetAttribute(AuxFanSound);

        if (isActive != null )
        {
            if (auxFanSound.isPlaying != isActive.Value)
            {
                if (isActive.Value)
                {
                    auxFanSound.Play();
                    on_off = 1;
                    GetSoundIDNumberAndPlaySound();
                }
                else
                {
                    auxFanSound.Stop();
                    on_off = 2;
                    GetSoundIDNumberAndStopSound();
                }
            }
        }

        for (int i = 0; i < simObject.numFloatAttributes; i++)
        {
            SimObject.SimObjectAttribute attribute = simObject.floatAttributes[i];

            switch (attribute.name)
            {
                case Attribute_FanIDNumber:
                    FanIDNumber = ((SimObject.FloatAttribute)attribute).Value;
                    break;
            }
        }
    }

    void GetSoundIDNumberAndPlaySound()
    {
        var temp = GameObject.FindGameObjectsWithTag("SoundSwitchable");

        auxPipeSound = new AuxPipeSound[temp.Length];
        for (int i = 0; i < auxPipeSound.Length; i++)
        {
            auxPipeSound[i] = temp[i].GetComponent<AuxPipeSound>();
        }

        audio = new AudioSource[temp.Length];
        for (int i = 0; i < audio.Length; i++)
        {
            audio[i] = temp[i].GetComponentInChildren<AudioSource>();
        }

        foreach (var auxPipe in auxPipeSound)
        {
            if (auxPipe.soundIDNumber == FanIDNumber)   //???????? this cant be right 
            {
                foreach (var audioSource in audio)
                {
                    audioSource.Play();
                }            
            }          
        }
    }

    void GetSoundIDNumberAndStopSound()
    {
        var temp = GameObject.FindGameObjectsWithTag("SoundSwitchable");
        auxPipeSound = new AuxPipeSound[temp.Length];
        for (int i = 0; i < auxPipeSound.Length; i++)
        {
            auxPipeSound[i] = temp[i].GetComponent<AuxPipeSound>();
        }

        audio = new AudioSource[temp.Length];
        for (int i = 0; i < audio.Length; i++)
        {
            audio[i] = temp[i].GetComponentInChildren<AudioSource>();
        }

        foreach (var auxPipe in auxPipeSound)
        {
            if (auxPipe.soundIDNumber == FanIDNumber)
            {
                foreach (var audioSource in audio)
                {
                    audioSource.Stop();
                }
            }
        }
    }
}

This is the script for my soundSpot

using UnityEngine;
using System.Collections;

public class AuxPipeSound : MonoBehaviour
{
    private const string Attribute_soundOn_Off =  "soundOn_Off";
    private const string Attribute_volume =       "volume";
    private const string Attribute_maxDistance =  "maxDistance";
    private const string Attribute_minDistance =  "minDistance";
    private const string Attribute_doppler =      "dopplerLevel";
    private const string Attribute_spread =       "spread";
    private const string Attribute_pitch =        "pitch";
    private const string Attibute_showSphere =    "showSphere";
    private const string Attibute_soundIDNumber = "SoundIDNumber";
    //private const string Attribute_playDelayed =  "playDelayed";
    private  AudioSource   auxPipeSound;
    private MeshRenderer sphereMesh;
    public float soundIDNumber;

    void Start()
    {

        sphereMesh = GetComponentInChildren<MeshRenderer>();
        auxPipeSound = GetComponentInChildren<AudioSource>();
        SimObject simObject = GetComponent<SimObject>();
        simObject.AddAttributeWatcher(UpdateSound);

    }
    private void OnDisable()
    {
        SimObject simObject = GetComponent<SimObject>();
        if (simObject) simObject.RemoveAttributeWatcher(UpdateSound);      
    }

    private void UpdateSound(SimObject simObject)
    {

        SimObject.BoolAttribute isActive = (SimObject.BoolAttribute)simObject.GetAttribute(Attribute_soundOn_Off);

        if (isActive != null)
        {
            if (auxPipeSound.isPlaying != isActive.Value)
            {
                if (isActive.Value)
                {
                    auxPipeSound.Play();
                }
                else
                {
                    auxPipeSound.Stop();
                }
            }
        }

        SimObject.BoolAttribute MeshisActive = (SimObject.BoolAttribute)simObject.GetAttribute(Attibute_showSphere);

      

        if (MeshisActive != null)
        {
            if (sphereMesh.isVisible != MeshisActive.Value)
            {
                if (MeshisActive.Value)
                {
                    sphereMesh.enabled = true;
                }
                else
                {
                    sphereMesh.enabled = false;
                }
            }
        }

        for (int i = 0; i < simObject.numFloatAttributes; i++)
        {
            SimObject.SimObjectAttribute attribute = simObject.floatAttributes[i];

            switch (attribute.name)
            {
                case Attribute_volume:
                    auxPipeSound.volume = ((SimObject.FloatAttribute)attribute).Value;
                    break;

                case Attribute_maxDistance:
                    auxPipeSound.maxDistance = ((SimObject.FloatAttribute)attribute).Value;
                    break;

                case Attribute_minDistance:
                    auxPipeSound.minDistance = ((SimObject.FloatAttribute)attribute).Value;
                    break;

                case Attribute_doppler:
                    auxPipeSound.dopplerLevel = ((SimObject.FloatAttribute)attribute).Value;
                    break;

                case Attribute_spread:
                    auxPipeSound.spread = ((SimObject.FloatAttribute)attribute).Value;
                    break;

                case Attribute_pitch:
                    auxPipeSound.pitch = ((SimObject.FloatAttribute)attribute).Value;
                    break;

                case Attibute_soundIDNumber:
                    soundIDNumber = ((SimObject.FloatAttribute)attribute).Value;
                    break;
            }
        }

    }

}