How to play multiple audioclips from the same object?

I have a spaceship object and I want to play ambient sound, engine sounds and weapon sounds from the same object. But so far I only could add empty game objects to the spaceship and setting each one as audio source and play the sounds that way.

Is there an easy way to do it without creating multiple child objects?

I’ve simply sorted the text from above and also included a C# version of the same:

JS:

// define the audio clips
var clipAmb: AudioClip;
var clipEngine: AudioClip;
var clipWeapon1: AudioClip; 
var clipWeapon2: AudioClip;

private var audioAmb: AudioSource;
private var audioEngine: AudioSource;
private var audioWeapon1: AudioSource;
private var audioWeapon2: AudioSource;

function AddAudio(clip:AudioClip, loop: boolean, playAwake: boolean, vol: float): AudioSource{ 
    var newAudio = gameObject.AddComponent(AudioSource);
    newAudio.clip = clip; 
    newAudio.loop = loop;
    newAudio.playOnAwake = playAwake;
    newAudio.volume = vol; 
    return newAudio; 
}

function Awake(){
    // add the necessary AudioSources:
    audioAmb = AddAudio(clipAmb, true, true, 0.2);
    audioEngine = AddAudio(clipEngine, true, true, 0.4);
    audioWeapon1 = AddAudio(clipWeapon1, false, false, 0.8);
    audioWeapon2 = AddAudio(clipWeapon2, false, false, 0.8); 
    } 

You can then use the audio sources like this:

   audioWeapon1.Play();
   audioEngine.pitch *= curVelocity/maxVelocity;

C#:

// define the audio clips
public AudioClip clipAmb;
public AudioClip clipEngine;
public AudioClip clipWeapon1; 
public AudioClip clipWeapon2;

private AudioSource audioAmb;
private AudioSource audioEngine;
private AudioSource audioWeapon1;
private AudioSource audioWeapon2;

public AudioSource AddAudio(AudioClip clip, bool loop, bool playAwake, float vol) { 
    public AudioSource newAudio = gameObject.AddComponent(AudioSource);
    newAudio.clip = clip; 
    newAudio.loop = loop;
    newAudio.playOnAwake = playAwake;
    newAudio.volume = vol; 
    return newAudio; 
}

public void Awake(){
    // add the necessary AudioSources:
    audioAmb = AddAudio(clipAmb, true, true, 0.2);
    audioEngine = AddAudio(clipEngine, true, true, 0.4);
    audioWeapon1 = AddAudio(clipWeapon1, false, false, 0.8);
    audioWeapon2 = AddAudio(clipWeapon2, false, false, 0.8); 
    } 

You can then use the audio sources like this:

   audioWeapon1.Play();
   audioEngine.pitch *= curVelocity/maxVelocity;

You can attach several AudioSources to the same object in the Inspector, and get them in an array at Awake with GetComponents(AudioSource) - but knowing who’s who may become a problem, since there’s no component identifier.

A better alternative is to add the AudioSources at Awake - the script SoundController.js in the Car Tutorial adds as many as 10 AudioSource components to the car!

You could do something like this:

// define the audio clips:
var clipAmb: AudioClip;
var clipEngine: AudioClip;
var clipWeapon1: AudioClip;
var clipWeapon2: AudioClip;

private var audioAmb: AudioSource;
private var audioEngine: AudioSource;
private var audioWeapon1: AudioSource;
private var audioWeapon2: AudioSource;

function AddAudio(clip:AudioClip, loop: boolean, playAwake: boolean, vol: float): AudioSource {
  var newAudio = gameObject.AddComponent(AudioSource);
  newAudio.clip = clip;
  newAudio.loop = loop;
  newAudio.playOnAwake = playAwake;
  newAudio.volume = vol;
  return newAudio;
}

function Awake(){
  // add the necessary AudioSources:
  audioAmb = AddAudio(clipAmb, true, true, 0.2);
  audioEngine = AddAudio(clipEngine, true, true, 0.4);
  audioWeapon1 = AddAudio(clipWeapon1, false, false, 0.8);
  audioWeapon2 = AddAudio(clipWeapon2, false, false, 0.8);
}

You can then use the audio sources like this:

  audioWeapon1.Play();
  audioEngine.pitch *= curVelocity/maxVelocity;

There’s also a PlayOneShot(AudioClip clip, float volumeScale) function that seems to be playing overlapping sounds as I use it right now. I’m playing pretty short clips, but they seem to be playing simultaneously.

Short:

If you have some AudioClips clip1 and clip2 that you want to play from an AudioSource on the GameObject gameObject1, you can use:
gameObject1.GetComponent().PlayOneShot(clip1);
gameObject1.GetComponent().PlayOneShot(clip2);

Long:

If you want to store a set of audio clips and play them without dealing with uploading them in your other scripts, here’s a script called MoreAudioClips.

  1. Attach MoreAudioClips script to a GameObject with an AudioSource.

  2. Upload your AudioClips in the Inspector view of MoreAudioClips. You can also modify the volumes if you want, but they default to 1.

  3. Play the AudioClips from elsewhere by using: GetComponent().PlayClip[2]; to play the 3rd clip in the list, or GetComponent().PlayRandomClip(); to play a random clip in the list.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    [RequireComponent(typeof(AudioSource))]
    public class MoreAudioClips : MonoBehaviour {
    ///


    /// MoreAudioClips: stores a list of audio clips so that they can be played from an audio source on the gameobject
    ///

    /// Attached to: a gameobject that has an audio source and you want to use multiple audio clips for
    public List clips; // store the audio clips
    public List volumes;

    void Start()
    {
        while (volumes.Count < clips.Count) //ensure volumes are valid for the clip indices
        {
            volumes.Add(1f); // set a default volume of 1 for clips with no specified volume
        }
    }
    
    
    public void PlayClip(int clipNum)
    { // used to play a specific clip from another script
      // GetComponent<MoreAudioClips>().PlayClip[2] would play the 3rd clip (index 2) that you set in the Inspector list for MoreAudioCLips
        if (clips.Count > 0 && clipNum >= 0 && clipNum < clips.Count)
            GetComponent<AudioSource>().PlayOneShot(clips[clipNum], volumes[clipNum]); //uses the AudioSource on the current gameObject
    }
    
    public void PlayRandomClip()
    { // used to play a random clip from the set of clips
        if (clips.Count > 0)
        {
            int clipNum = Random.Range(0, clips.Count - 1);
            GetComponent<AudioSource>().PlayOneShot(clips[clipNum], volumes[clipNum]);
        }
    }
    

    }