Change songs after each completed level?

How can you change songs after each completed level?

2 Likes

Hi Dominic,

You could consider having an AudioClip array within your MusicPlayer;

public AudioClip[] audioClips;

Then drag in some music files into the exposed field in the Inspector.

You will probably already have code for playing the music, but just continually, so you’ll need to remember to remove the existing AudioClip you have in the AudioSource component on MusicPlayer. Also, untick PlayOnAwake.

You’ll need to add some additional methods to handle the Play and Stop functionality, but in order for them to work you’ll need to get a reference to the AudioSource component on the MusicManager, as you’ll need that in both the Play and Stop methods it would be more efficient to have a member variable store it.

private AudioSource _audioSource;

You will then need to use GetComponent<T> to set that reference which you can do in the Awake method;

    private void Awake()
    {
        if (instance != null)
        {
            Destroy(gameObject);
            Debug.Log("Duplicate MusicPlayer self-destructing!");
        }
        else
        {
            instance = this;
            GameObject.DontDestroyOnLoad(gameObject);
            _audioSource = GetComponent<AudioSource>(); 
        }
    }

You could consider adding a PlayRandom method, and then use Random.Range in order to get a random number which you could use to play a clip from your audioClips array.

    /// <summary>
    /// Plays a random audio clip from the array
    /// </summary>
    public void PlayRandom()
    {
        int audioClipIndex = Random.Range(0, audioClips.Length);

        instance.Play(audioClipIndex);
    }

    /// <summary>
    /// Plays a specific audio clip based on the specified audioClipIndex
    /// </summary>
    /// <param name="audioClipIndex">The index of the AudioClip to play</param>
    public void Play(int audioClipIndex)
    {
        _audioSource.clip = instance.audioClips[audioClipIndex];

        _audioSource.Play();
    }

    /// <summary>
    /// Stops the AudioClip playing
    /// </summary>
    public void Stop()
    {
        _audioSource.Stop();
    }

The full MusicPlayer script may look like this;

using UnityEngine;

public class MusicPlayer : MonoBehaviour
{
    public AudioClip[] audioClips;

    static MusicPlayer instance = null;

    private AudioSource _audioSource;

    /// <summary>
    /// Pre-Initialisation
    /// </summary>
    private void Awake()
    {
        if (instance != null)
        {
            Destroy(gameObject);
            Debug.Log("Duplicate MusicPlayer self-destructing!");
        }
        else
        {
            instance = this;
            GameObject.DontDestroyOnLoad(gameObject);
            _audioSource = GetComponent<AudioSource>();
            instance.PlayRandom();
        }
    }

    /// <summary>
    /// Plays a random audio clip from the array
    /// </summary>
    public void PlayRandom()
    {
        int audioClipIndex = Random.Range(0, audioClips.Length);

        instance.Play(audioClipIndex);
    }

    /// <summary>
    /// Plays a specific audio clip based on the specified audioClipIndex
    /// </summary>
    /// <param name="audioClipIndex">The index of the AudioClip to play</param>
    public void Play(int audioClipIndex)
    {
        _audioSource.clip = instance.audioClips[audioClipIndex];

        _audioSource.Play();
    }

    /// <summary>
    /// Stops the AudioClip playing
    /// </summary>
    public void Stop()
    {
        _audioSource.Stop();
    }

}

Note, in the Awake method above, I also added a line to call PlayRandom, this will play an AudioClip instantly, like PlayOnAwake did previously.

If you want to play specific AudioClips on specific levels, you could load the array with your relevent clips, and then perhaps use the Scene.buildIndex value as the index, so the Start scene is 0, Level1 is 1, Level2 is 2 and so on.

You will of course need to get a reference to the MusicPlayer and call the Play method on each level, you could consider doing this from LevelManager.

Hope this helps :slight_smile:

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms