Can I play multiple AudioSources from one gameobject?

I’ve searched and read many different posts and still haven’t been able to accomplish this. Ideally I’d like to attach several different AudioSource components to a game object and be able to trigger them from a script attached to that object.

I’ve tried several different things and no matter which method I try, there seems to be a different issue keeping me from being able to play the sounds properly.

1- I want to be able to set some sounds to loop and others to not loop. Because of this, I need to create Audio Sources and not just use audio.PlayOneShot or AudioSource.PlayClipAtPoint. (Not to mention that I want to be able to set other parameters easily, such as the 3D settings and priority, volume and pitch.)

2- I need all of the sounds to be 3D positioned on the game object, so creating a game object for each sound and calling them in the script using TireRollLoop.Play(); for example, will not work, as the sounds are tied to their own game object’s position in the scene.

3- Using audio.clip = TireRollLoop; to set the sound and then playing the sound using audio.Play() does not work because I need to be able to play some sounds at the same time.

Sorry for the lengthy question but I’ve been running into all sorts of issues. I am not a programmer but can usually make things work by trial and error.

That’s a good question! You can add several AudioClips to the same object, and get them with GetComponents:

var audio1: AudioSource;
var audio2: AudioSource;
var audio3: AudioSource;

function Start(){
    var aSources = GetComponents(AudioSource);
    audio1 = aSources[0];
    audio2 = aSources[1];
    audio3 = aSources[2];
}

// you can then access the different AudioSources using the variables you've set:

    audio2.Play();
    audio1.Stop();

NOTE: Presently, the AudioSources are added to the array in the order they appear in the Inspector, as we could expect. Unfortunately, nobody knows if this order may be different in future Unity versions. If you want to be sure about that, you can set different Priority values (for instance) and check them in Start.

if you use c#, the code is

AudioSource correctAudio;
AudioSource errorAudio;

void Start() {
    AudioSource[] audios = GetComponents<AudioSource>();
    errorAudio = audios[0];
    correctAudio = audios[1];
}

void OnGUI() {
    if (answer == currAnswer) 
        correctAudio.Play();
    else
	errorAudio.Play();
}

The easiest way to manage multiple audio sources is to have public references to them and assign them in the inspector:

  • Add multiple audio source components to your GameObject
  • Create a public AudioSource variable for each one
  • Assign their values by dragging the AudioSource component into the variable slot in the inspector
  • Access them directly from code

i did only

public AudioSource correctAudio;

then
where i wanted sound to play i did

correctAudio.Play();

only thing is you need to have GameObject created with AudioSource on it and add to the public spot. doing it this way allows me not to use as much coding and can add as many sounds as i like to play i’m just not sure how much space would be needed this way if its more or less than other way i know using AudioClip.

Just create child objects with different AudioSource’s and link code there.

I get the following error message:

“Cannot convert ‘UnityEngine.Component’ to ‘UnityEngine.AudioClip’.”

while using this line of code:
function Start(){
var aSources = GetComponents(AudioSource);
audio1 = aSources[0];

For people in 2019 (trying to use @aldonaletto method), I personally avoid assigning variables through the inspector/editor as it is relatively simplistic and can lead to issues when working in teams etc across multiple scenes.

1)Assign your variables, in my case they are ‘m_asPlayerSF’ which is used for Sound Effects, and m_asMusicMaster which is used for the the main music.

2)Within your start/awake function, create a var which will eventually be casted to an array of AudioSources, as seen in the following block of code…

var _audioSources = GetComponents(typeof(AudioSource)).Cast<AudioSource>().ToArray();
            m_asPlayerSF = _audioSources[0];
            m_asMusicMaster = _audioSources[1];
  1. Assign respective AudioSources to their scripted variables… In my inspector I have my first audio source utilized as my Sound Effects and another one directly after to handle main music, hence _audioSources[0] = SF and _audioSources[1] = MusicMaster

I have an audio system set up wherein I have loaded all my audio clips centrally and play them on demand by passing the requesting audioSource into the sound manager.

However, there is a complication wherein if I want to overlay multiple looping sounds, I need to have multiple audio sources on an object, which is fine , so I created two in my script instantiated them and played my clips on them and then the world went crazy. See How to Keep Urine at Body Temperature

For some reason, when I create two audio Sources in an object only the latest one is ever used, even if I explicitly keep objects separated, playing a clip on one or the other plays the clip on the last one that was created, furthermore, either this last one is not created in the right place or somehow messes with the rolloff rules because I can hear it all across my level, havign just one source works fine, but putting a second one on it causes shit to go batshit insane.

Does anyone know the reason / solution for this ?

Some pseudocode :

guardSoundsSource = (AudioSource)gameObject.AddComponent(“AudioSource”);
guardSoundsSource.name = “Guard_Sounds_source”;
// Setup this source

guardThrusterSource = (AudioSource)gameObject.AddComponent(“AudioSource”);
guardThrusterSource.name = “Guard_Thruster_Source”;
// setup this source
// play using custom Sound manager
soundMan.soundMgr.playOnSource(guardSoundsSource,“Guard_Idle_loop”
,true,GameManager.Manager.PlayerType);
// this method prints out the name of the source the sound was to be played on and it always shows “Guard_Thruster_Source” even on the “Guard_Idle_loop” even though I clearly told it to use “Guard_Sounds_source”
unity
audio

Share
Improve this question
Follow
edited Dec 22 '14 at 21:48
user1430
asked Oct 21 '13 at 1:08

angryInsomniac
11111 silver badge77 bronze badges
2
When you set the .name property I believe you are setting/changing the name of the GameObject these component’s are attached to, not the components themselves, so the name printed will always be the last name set. When you add an AudioSource via code it’s going to have the default settings, which I think is 3D sound with default rolloff, so after adding the components you should set their properties how you want them. I think your code is working correctly, just the output is misleading. – Calvin Oct 21 '13 at 17:54
add a comment
1 Answer

2

I can’t speak exactly to the specific issue you are having, but I can say I am fairly certain you can add multiple of the same type of component to one GameObject. The best way I have found to do this is to access them is by using the “GetComponents” method call. Something like this should do:

AudioSource allMyAudioSources = GetComponents();

This will return an array of AudioSources, which you can then assign to different variables and access independently without freaking things out. Something like this in C#:

AudioSource thrusterSource;
AudioSource guardSource;

void Start() {
AudioSource allMyAudioSources = GetComponents();
thrusterSource = allMyAudioSources[0];
guardSource = allMyAudioSources1;
}

// These should no longer bug each other out!
guardSource.Play();
thrusterSource.Play();
EDIT: I thought it would be worth noting if it’s not obvious, I have found the Components will populate the array in sequence from top to bottom. So it will help to keep that in mind when assigning those sound files.