Big Game Project – Managing ambient sounds

Our game world consist of two areas different in mood. One is an island floating above the clouds and the other a dangerous jungle on the planet below. The island has a windy ambience and the jungle has recordings of a real jungle. Day and night is also important for gameplay, so I wanted different ambiences for those. It was difficult to find two wind recordings that were distinctively different enough, so I chose to always have the same for the island during day and night, but two different recordings for the island.

I wanted a system from which it is easy to change the ambience, and changing the ambience would mean fading out the current ambience while fading in the new ambience. The duration of the fades can be passed in as a parameter because I wanted a fast transition when the player manually switches between the island and jungle levels with a keypress, and a slower transition when the ambience changes automatically with the time of day.

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

public enum AmbientSounds
{
    ISLAND,
    JUNGLE_DAY,
    JUNGLE_NIGHT,
    NONE,
}

public class Ambience
{
    public AudioSource audioSource;
    private float volume = 0f;
    public AmbientSounds identifier;
    private float currentFadeTime = 0f;
    private float fadeStartVolume;
    private float fadeTime = 0.2f;
    private bool fading = false;

    public void Initialize(AmbientAudio ambientAudio, AudioSource _audioSource, AmbientSounds _identifier)
    {
        identifier = _identifier;
        audioSource = _audioSource;
        audioSource.volume = 0f;
        volume = 0f;
        SetActive(false, 0f);
        audioSource.loop = true;
    }

    public void UpdateLayer(float deltaTime)
    {
        if (!fading)
            return;

        if (fadeTime == 0)
        {
            fading = false;
            audioSource.volume = volume;
            return;
        }

        currentFadeTime += deltaTime;
        if (currentFadeTime > fadeTime)
        {
            fading = false;
            currentFadeTime = fadeTime;
        }
        audioSource.volume = Mathf.Lerp(fadeStartVolume, volume, currentFadeTime / fadeTime);
    }

    public void SetActive(bool active, float fadeDuration = 0)
    {
        fadeTime = fadeDuration;
        fading = true;
        currentFadeTime = 0;
        fadeStartVolume = audioSource.volume;
        volume = active ? 1f : 0f;
    }
}

public class AmbientAudio : MonoBehaviour
{
    static AmbientAudio instance;
    public AudioSource jungle_daySource;
    public AudioSource jungle_nightSource;
    public AudioSource islandSource;
    public List<Ambience> ambiences;
    public AmbientSounds current;

    void Awake()
    {
        if (instance == null)
            instance = this;

        ambiences = new List<Ambience>();

        Ambience ambience1 = new Ambience();
        ambience1.Initialize(this, jungle_daySource, AmbientSounds.JUNGLE_DAY);
        ambiences.Add(ambience1);

        Ambience ambience2 = new Ambience();
        ambience2.Initialize(this, jungle_nightSource, AmbientSounds.JUNGLE_NIGHT);
        ambiences.Add(ambience2);

        Ambience ambience3 = new Ambience();
        ambience3.Initialize(this, islandSource, AmbientSounds.ISLAND);
        ambiences.Add(ambience3);
    }

    void Start()
    {
        for (int i = 0; i < ambiences.Count; i++)
        {
            ambiences[i].audioSource.Play();
            ChangeAmbience(AmbientSounds.NONE, 0f);
        }
        ChangeAmbience(AmbientSounds.ISLAND, 0);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
            ChangeAmbience(AmbientSounds.ISLAND, 2f);
        if (Input.GetKeyDown(KeyCode.Alpha2))
            ChangeAmbience(AmbientSounds.JUNGLE_DAY, 2f);
        if (Input.GetKeyDown(KeyCode.Alpha3))
            ChangeAmbience(AmbientSounds.JUNGLE_NIGHT, 2f);

        for (int i = 0; i < ambiences.Count; i++)
        {
            ambiences[i].UpdateLayer(Time.deltaTime);
        }
    }

    public static void ChangeAmbience(AmbientSounds newSound, float fadeDuration)
    {
        instance.current = newSound;
        for (int i = 0; i < instance.ambiences.Count; i++)
        {
            Ambience ambience = instance.ambiences[i];
            if (ambience.identifier == newSound)
                ambience.SetActive(true, fadeDuration);
            else
                ambience.SetActive(false, fadeDuration);
        }
    }

    public static AmbientSounds GetCurrent()
    {
        return instance.current;
    }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s