Audio Tagging

We are in the process of setting up audio options from our start menu. We would like to be able to set the volume for Sfx, Music, and Dialogue. I thought the best way to do this would just be to tag each of the audio clips as sfx, mus, or dia, and access them through script using there tag. However, it seems that audio clips cannot be tagged in the editor. Is there another way to achieve this? What’s the best way of manipulating the volume of different types of audio?

I currently have a project that deals with many AudioSources. While I currently only have one volume level, the system I use could easily be extended to fit your purposes.

The volume control script (called VolumeControl.js):

// Volumes stored into array as Sfx, Music, and Dialog indexed respectively
static var volumes : float[] = new float[3];
// audioSources stores a reference to each audio source in an ArrayList
// based on what volume level is controlling it (parallel array with volumes[])
static var audioSources : ArrayList[3] = new ArrayList[3];

public static function SetVolume(volumeGroup : int, volume : float) {
    if (volume != volumes[volumeGroup]) {
        volumes[volumeGroup] = volume;
        updateVolume(volumeGroup);
    }
}

//Send the new volume level to the audio sources
static function updateVolume(volumeGroup : int) {
    for (var i = 0; i < audioSources[volumeGroup].Count; i++) {
        var obj : GameObject = keys*;*

obj.BroadcastMessage(“UpdateVolume”, volumes[volumeGroup], SendMessageOptions.DontRequireReceiver);
}
}
public static function AddSource(audioSource : GameObject, volumeGroup : int) {
if (audioSources[volumeGroup] == null)
audioSources[volumeGroup] = new ArrayList();
audioSources[volumeGroup].Add(audioSource);
}
public static function GetVolume(volumeGroup : int) : float {
return volumes[volumeGroup];
}
That script might need some modifications to better suite your needs but it should work out. You will need to add a function that removes the audio sources from the ArrayList if you do delete the AudioSources.
Then this script goes into the audio sources themselves. (Borrowing an 2 ideas from aldonaletto’s answer.)
enum SoundGroup {Sfx, Music, Dialog}
var sGroup : SoundGroup = SoundGroup.Sfx;

private var startVol : float;
private var groupVol : float;

function Start() {
startVol = audio.volume;
switch (sGroup) {
case SoundGroup.Sfx:
groupVolume = VolumeControl.GetVolume(0);
VolumeControl.AddSource(gameObject, 0);
break;
case SoundGroup.Music:
groupVolume = VolumeControl.GetVolume(1);
VolumeControl.AddSource(gameObject, 1);
break;
case SoundGroup.Dialog:
groupVolume = VolumeControl.GetVolume(2);
VolumeControl.AddSource(gameObject, 2);
break;
}
audio.volume = groupVolume * startVolume;
}

function UpdateVolume(volume : float) {
groupVolume = volume;
audio.volume = groupVolume * startVolume;
}
These scripts will only cause slow downs when the volume changes and there are large amounts of AudioSources in the group being updated. All you need to do is call VolumeControl.SetVolume when the user touches the volume control. The system automatically checks to see if the volume level has changed and only updates if it has, so it is safe to call VolumeControl.SetVolume every frame, within the OnGui() function for instance.

You could define the global Sfx, Music and Dialog volumes in static variables in the volume control script, and have a special script attached to every object that has an AudioSource, which would define the type and the volume of the sound - something like this:

1- In the volume control script (let’s call it VolumeControl.js):

static var sfxVolume: float = 0.7;
static var musicVolume: float = 0.3;
static var dialogVolume: float = 0.8;

function OnGUI(){
    // adjust the volume of each type
}

2- Attach the script below to objects that have an AudioSource:

enum SoundType {Sfx, Music, Dialog}
var sType: SoundType = SoundType.Sfx; // define the sound type in the Inspector

private var iniVol: float;
private var gVol: float;

function Start(){
    iniVol = audio.volume; // save the local volume
}

function Update(){
    switch (sType){ // get the correct type volume
        case SoundType.Sfx: 
            gVol = VolumeControl.sfxVolume;
            break;
        case SoundType.Music: 
            gVol = VolumeControl.musicVolume;
            break;
        case SoundType.Dialog: 
            gVol = VolumeControl.dialogVolume;
            break;
    }
    audio.volume = iniVol * gVol;
}