Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

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

Discussion in 'Scripting' started by KenClemson, Dec 9, 2016.

  1. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    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.

    Code (CSharp):
    1. public class findObjects : MonoBehaviour
    2. {
    3.     public AudioSource[] aSource;
    4.  
    5.  
    6.  
    7.     void Start()
    8.  
    9.     {
    10.         aSource = GameObject.FindGameObjectWithTag("SoundSpots").GetComponentsInChildren<AudioSource>();
    11.     }
    12.  
    13.    
    14.     // Update is called once per frame
    15.     void Update ()
    16.     {
    17.         foreach(AudioSource aS in aSource)
    18.         {
    19.             aS.Play();
    20.         }
    21.    
    22.     }
    23. }
     
  2. Tzan

    Tzan

    Joined:
    Apr 5, 2009
    Posts:
    736
    https://docs.unity3d.com/ScriptReference/GameObject.html

    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.
     
  3. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    Yes sorry, Im a bit of a newb when it comes to that, Im not sure how to get my AudioSource after FindGameObjectsWithTag("SoundSpots") ??????

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class findObjects : MonoBehaviour
    5. {
    6.     public AudioSource[] aSource;
    7.  
    8.  
    9.  
    10.     void Start()
    11.  
    12.     {
    13.         aSource = GameObject.FindGameObjectsWithTag("SoundSpots").  ??????????
    14.     }
    15.  
    16.    
    17.     // Update is called once per frame
    18.     void Update ()
    19.     {
    20.         foreach(AudioSource aS in aSource)
    21.         {
    22.             aS.Play();
    23.         }
    24.    
    25.     }
    26. }
     
  4. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    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

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class FindSoundSpots : MonoBehaviour {
    4.     private AudioSource[] _audioSources;
    5.  
    6.     private void Start () {
    7.         var temp = GameObject.FindGameObjectsWithTag("SoundSpots");
    8.         _audioSources = new AudioSource[temp.Length];
    9.  
    10.         for (int i = 0; i < _audioSources.Length; i++) {
    11.             _audioSources[i] = temp[i].GetComponent<AudioSource>();
    12.         }
    13.     }
    14. }
    15.  
    or if you really want a one liner you could do something like this
    Code (CSharp):
    1. using System.Linq;
    2. using UnityEngine;
    3.  
    4. public class FindSoundSpots : MonoBehaviour {
    5.     private AudioSource[] _audioSources;
    6.  
    7.     private void Start () {
    8.         _audioSources = GameObject.FindGameObjectsWithTag("SoundSpots").Select(x => x.GetComponent<AudioSource>()).ToArray();
    9.     }
    10. }
    11.  
    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.
     
  5. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    Awesome thanks !'ll test it out and see how it works.
     
  6. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    I was just playing around with your code, where would I actually put _audioSources.Play(); ?
    Sorry for another nube question.
     
  7. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    would depend on what you are trying to do and when you want them to play
     
  8. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    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.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class FindSoundSpots : MonoBehaviour
    4. {
    5.     private AudioSource[] _audioSources;
    6.  
    7.     private void Start()
    8.     {
    9.         var temp = GameObject.FindGameObjectsWithTag("SoundSpots");
    10.         _audioSources = new AudioSource[temp.Length];
    11.  
    12.         for (int i = 0; i < _audioSources.Length; i++)
    13.         {
    14.             _audioSources[i] = temp[i].GetComponent<AudioSource>();
    15.         }
    16.     }
    17.  
    18.  
    19.  
    20.     public void TurnOn()
    21.     {
    22.        // _audioSources.PLay  ...but this doesnt seem to work ??
    23.      
    24.         //Do you need to do like a    foreach(AudioSource aSource in _audioSources)
    25.         //  {   aSource.Play();    }   but that doesnt seem to work either
    26.     }
    27.  
    28.     public void TurnOff()
    29.     {
    30.  
    31.     }
    32. }
     
  9. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    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
    Code (CSharp):
    1. _audioSources[i] = temp[i].GetComponent<AudioSource>();
    with
    Code (CSharp):
    1. _audioSources[i] = temp[i].GetComponentInChildren<AudioSource>();
     
  10. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    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
    Code (CSharp):
    1.     private AudioSource[] _audioSources;
    2.  
    3.     public void TurnOn()
    4.     {
    5.         var temp = GameObject.FindGameObjectsWithTag("SoundSpot");
    6.         _audioSources = new AudioSource[temp.Length];
    7.         for (int i = 0; i < _audioSources.Length; i++)
    8.         {
    9.             _audioSources[i] = temp[i].GetComponentInChildren<AudioSource>();
    10.             _audioSources[i].Play();
    11.             Debug.Log("all audio sources are on");
    12.         }
    13.     }
    14.  
    15.     public void TurnOff()
    16.     {
    17.         var temp = GameObject.FindGameObjectsWithTag("SoundSpot");
    18.         _audioSources = new AudioSource[temp.Length];
    19.  
    20.         for (int i = 0; i < _audioSources.Length; i++)
    21.         {
    22.             _audioSources[i] = temp[i].GetComponentInChildren<AudioSource>();
    23.             _audioSources[i].Stop();
    24.             Debug.Log("all audio sources are off");
    25.  
    26.         }
    27.     }
     
  11. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    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.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class FindSoundSpots : MonoBehaviour {
    4.     private AudioSource[] _audioSources;
    5.  
    6.     private void Start() {
    7.         var temp = GameObject.FindGameObjectsWithTag("Soundspot");
    8.         _audioSources = new AudioSource[temp.Length];
    9.         for (int i = 0; i < _audioSources.Length; i++) {
    10.             _audioSources[i] = temp[i].GetComponentInChildren<AudioSource>();
    11.         }
    12.     }
    13.  
    14.     public void TurnOn() {
    15.         foreach (var audioSource in _audioSources) {
    16.             audioSource.Play();
    17.         }
    18.     }
    19.  
    20.     public void TurnOff() {
    21.         foreach (var audioSource in _audioSources) {
    22.             audioSource.Stop();
    23.         }
    24.     }
    25. }
    26.  
    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.
     
  12. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    OK I see, yes that makes much more sense. Thanks you.
     
  13. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    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
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class AuxiliaryFan : MonoBehaviour
    5. {
    6.     private const string AuxFanSound = "AuxFanSound";
    7.     private const string Attribute_FanIDNumber = "FanIDNumber";
    8.     public AudioSource auxFanSound;
    9.     //private GameObject[] simAudio;
    10.     private AudioSource[] audio;
    11.  
    12.     public float FanIDNumber;
    13.     private AuxPipeSound[] auxPipeSound;
    14.  
    15.     private int on_off;
    16.  
    17.     private void Start()
    18.     {
    19.         SimObject simOBject = transform.parent.GetComponent<SimObject>();
    20.         simOBject.AddAttributeWatcher(UpdateSound);
    21.  
    22.     }
    23.  
    24.     private void OnDisable()
    25.     {
    26.         SimObject simObject = transform.parent.GetComponent<SimObject>();
    27.         if (simObject) simObject.RemoveAttributeWatcher(UpdateSound);
    28.     }
    29.  
    30.     private void UpdateSound(SimObject simObject)
    31.     {
    32.         SimObject.BoolAttribute isActive = (SimObject.BoolAttribute)simObject.GetAttribute(AuxFanSound);
    33.  
    34.         if (isActive != null )
    35.         {
    36.             if (auxFanSound.isPlaying != isActive.Value)
    37.             {
    38.                 if (isActive.Value)
    39.                 {
    40.                     auxFanSound.Play();
    41.                     on_off = 1;
    42.                     GetSoundIDNumberAndPlaySound();
    43.                 }
    44.                 else
    45.                 {
    46.                     auxFanSound.Stop();
    47.                     on_off = 2;
    48.                     GetSoundIDNumberAndStopSound();
    49.                 }
    50.             }
    51.         }
    52.  
    53.         for (int i = 0; i < simObject.numFloatAttributes; i++)
    54.         {
    55.             SimObject.SimObjectAttribute attribute = simObject.floatAttributes[i];
    56.  
    57.             switch (attribute.name)
    58.             {
    59.                 case Attribute_FanIDNumber:
    60.                     FanIDNumber = ((SimObject.FloatAttribute)attribute).Value;
    61.                     break;
    62.             }
    63.         }
    64.     }
    65.  
    66.     void GetSoundIDNumberAndPlaySound()
    67.     {
    68.         var temp = GameObject.FindGameObjectsWithTag("SoundSwitchable");
    69.  
    70.         auxPipeSound = new AuxPipeSound[temp.Length];
    71.         for (int i = 0; i < auxPipeSound.Length; i++)
    72.         {
    73.             auxPipeSound[i] = temp[i].GetComponent<AuxPipeSound>();
    74.         }
    75.  
    76.         audio = new AudioSource[temp.Length];
    77.         for (int i = 0; i < audio.Length; i++)
    78.         {
    79.             audio[i] = temp[i].GetComponentInChildren<AudioSource>();
    80.         }
    81.  
    82.         foreach (var auxPipe in auxPipeSound)
    83.         {
    84.             if (auxPipe.soundIDNumber == FanIDNumber)   //???????? this cant be right
    85.             {
    86.                 foreach (var audioSource in audio)
    87.                 {
    88.                     audioSource.Play();
    89.                 }            
    90.             }          
    91.         }
    92.     }
    93.  
    94.     void GetSoundIDNumberAndStopSound()
    95.     {
    96.         var temp = GameObject.FindGameObjectsWithTag("SoundSwitchable");
    97.         auxPipeSound = new AuxPipeSound[temp.Length];
    98.         for (int i = 0; i < auxPipeSound.Length; i++)
    99.         {
    100.             auxPipeSound[i] = temp[i].GetComponent<AuxPipeSound>();
    101.         }
    102.  
    103.         audio = new AudioSource[temp.Length];
    104.         for (int i = 0; i < audio.Length; i++)
    105.         {
    106.             audio[i] = temp[i].GetComponentInChildren<AudioSource>();
    107.         }
    108.  
    109.         foreach (var auxPipe in auxPipeSound)
    110.         {
    111.             if (auxPipe.soundIDNumber == FanIDNumber)
    112.             {
    113.                 foreach (var audioSource in audio)
    114.                 {
    115.                     audioSource.Stop();
    116.                 }
    117.             }
    118.         }
    119.     }
    120. }
     
  14. KenClemson

    KenClemson

    Joined:
    Oct 6, 2016
    Posts:
    24
    This is the script for my soundSpot
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class AuxPipeSound : MonoBehaviour
    5. {
    6.     private const string Attribute_soundOn_Off =  "soundOn_Off";
    7.     private const string Attribute_volume =       "volume";
    8.     private const string Attribute_maxDistance =  "maxDistance";
    9.     private const string Attribute_minDistance =  "minDistance";
    10.     private const string Attribute_doppler =      "dopplerLevel";
    11.     private const string Attribute_spread =       "spread";
    12.     private const string Attribute_pitch =        "pitch";
    13.     private const string Attibute_showSphere =    "showSphere";
    14.     private const string Attibute_soundIDNumber = "SoundIDNumber";
    15.     //private const string Attribute_playDelayed =  "playDelayed";
    16.     private  AudioSource   auxPipeSound;
    17.     private MeshRenderer sphereMesh;
    18.     public float soundIDNumber;
    19.  
    20.     void Start()
    21.     {
    22.  
    23.         sphereMesh = GetComponentInChildren<MeshRenderer>();
    24.         auxPipeSound = GetComponentInChildren<AudioSource>();
    25.         SimObject simObject = GetComponent<SimObject>();
    26.         simObject.AddAttributeWatcher(UpdateSound);
    27.  
    28.     }
    29.     private void OnDisable()
    30.     {
    31.         SimObject simObject = GetComponent<SimObject>();
    32.         if (simObject) simObject.RemoveAttributeWatcher(UpdateSound);      
    33.     }
    34.  
    35.     private void UpdateSound(SimObject simObject)
    36.     {
    37.  
    38.         SimObject.BoolAttribute isActive = (SimObject.BoolAttribute)simObject.GetAttribute(Attribute_soundOn_Off);
    39.  
    40.         if (isActive != null)
    41.         {
    42.             if (auxPipeSound.isPlaying != isActive.Value)
    43.             {
    44.                 if (isActive.Value)
    45.                 {
    46.                     auxPipeSound.Play();
    47.                 }
    48.                 else
    49.                 {
    50.                     auxPipeSound.Stop();
    51.                 }
    52.             }
    53.         }
    54.  
    55.         SimObject.BoolAttribute MeshisActive = (SimObject.BoolAttribute)simObject.GetAttribute(Attibute_showSphere);
    56.  
    57.      
    58.  
    59.         if (MeshisActive != null)
    60.         {
    61.             if (sphereMesh.isVisible != MeshisActive.Value)
    62.             {
    63.                 if (MeshisActive.Value)
    64.                 {
    65.                     sphereMesh.enabled = true;
    66.                 }
    67.                 else
    68.                 {
    69.                     sphereMesh.enabled = false;
    70.                 }
    71.             }
    72.         }
    73.  
    74.         for (int i = 0; i < simObject.numFloatAttributes; i++)
    75.         {
    76.             SimObject.SimObjectAttribute attribute = simObject.floatAttributes[i];
    77.  
    78.             switch (attribute.name)
    79.             {
    80.                 case Attribute_volume:
    81.                     auxPipeSound.volume = ((SimObject.FloatAttribute)attribute).Value;
    82.                     break;
    83.  
    84.                 case Attribute_maxDistance:
    85.                     auxPipeSound.maxDistance = ((SimObject.FloatAttribute)attribute).Value;
    86.                     break;
    87.  
    88.                 case Attribute_minDistance:
    89.                     auxPipeSound.minDistance = ((SimObject.FloatAttribute)attribute).Value;
    90.                     break;
    91.  
    92.                 case Attribute_doppler:
    93.                     auxPipeSound.dopplerLevel = ((SimObject.FloatAttribute)attribute).Value;
    94.                     break;
    95.  
    96.                 case Attribute_spread:
    97.                     auxPipeSound.spread = ((SimObject.FloatAttribute)attribute).Value;
    98.                     break;
    99.  
    100.                 case Attribute_pitch:
    101.                     auxPipeSound.pitch = ((SimObject.FloatAttribute)attribute).Value;
    102.                     break;
    103.  
    104.                 case Attibute_soundIDNumber:
    105.                     soundIDNumber = ((SimObject.FloatAttribute)attribute).Value;
    106.                     break;
    107.             }
    108.         }
    109.  
    110.     }
    111.  
    112. }
    113.