Shuffle Music Playlist with FMOD in Unity

If our game doesn’t need any music transitions and we just want to throw a bunch of events in Unity’s inspector and let them play following a shuffle behaviour, we can do that easily by writing some C# code. We will also take a look on how to use the User Properties of an FMOD Event to retrieve pre-defined information, in our case we will get the artist and song name of each track.

Preparation in FMOD Studio

Drag some of your music files into FMOD’s Events tab and select the option to create 2D events:

FMOD Studio Events tab
FMOD Studio Events tab

Look for the Properties section at the right side of the event window, you can enter information about the event in the User Properties field. We will enter the artist and song name:

FMOD Studio Event User Properties
FMOD Studio Event User Properties

Build the master bank and head over to Unity.

Code for the shuffle behaviour

Create a new script named ShufflePlaylist.cs and declare an array of EventReferences, that will be filled with our event references in the inspector. Also declare an FMOD EventInstance and the string variables artistName and songName:

public FMODUnity.EventReference[] fmodPaths;
private FMOD.Studio.EventInstance instance;
private string artistName,songName;

Now create a method named ShuffleMusic() that takes an array of EventReferences as a parameter. We will use the Fisher–Yates shuffle algorithm to loop through the array and shuffle the events:

    void ShuffleMusic(FMODUnity.EventReference[] eventReferences)
    {
        for (int i = eventReferences.Length - 1; i > 0; i--)
        {
            int rnd = UnityEngine.Random.Range(0, i);
            FMODUnity.EventReference temp = eventReferences[i];
            eventReferences[i] = eventReferences[rnd];
            eventReferences[rnd] = temp;
        }

        for (int i = 0; i < eventReferences.Length; i++)
        {
            Debug.Log(eventReferences[i].Path);
        }

        StartCoroutine(PlayMusic(eventReferences));
    }

We now create the Coroutine PlayMusic() and pass the shuffled array as a parameter:

IEnumerator PlayMusic(FMODUnity.EventReference[] eventReferences)
    {
        for (int i = 0; i < eventReferences.Length; i++)
        {
            instance = FMODUnity.RuntimeManager.CreateInstance(eventReferences[i]);

            FMOD.Studio.PLAYBACK_STATE playbackState;
            instance.getPlaybackState(out playbackState);

            if (playbackState != FMOD.Studio.PLAYBACK_STATE.PLAYING)
            {
                FMOD.Studio.EventDescription eD;
                instance.getDescription(out eD);

                int userPropertyCount;
                eD.getUserPropertyCount(out userPropertyCount);

                FMOD.Studio.USER_PROPERTY[] userProperties = new FMOD.Studio.USER_PROPERTY[
                    userPropertyCount
                ];

                for (int j = 0; j < userPropertyCount; j++)
                {
                    eD.getUserPropertyByIndex(j, out userProperties[j]);
                }

                if (userProperties.Length > 1)
                {
                    artistName = userProperties[0].stringValue();
                    songName = userProperties[1].stringValue();

                    Debug.Log("Artist: " + artistName);
                    Debug.Log("Song: " + songName);
                }

                instance.start();
                instance.release();

                instance.getPlaybackState(out playbackState);
                while (playbackState != FMOD.Studio.PLAYBACK_STATE.STOPPED)
                {
                    instance.getPlaybackState(out playbackState);
                    yield return null;
                }

                instance.clearHandle();

                while (instance.isValid())
                {
                    yield return null;
                }
            }
        }
        ShuffleMusic(fmodPaths);
    }

Essentially, we loop through the array and directly create an FMOD EventInstance. We check if the instance is not playing right now and get the EventDescription of our instance. We need this step to actually retrieve the User Properties of the FMOD Event. To do this we get the number of User Properties present in the event by calling getUserPropertyCount(), we declare an array of the FMOD.Studio.USER_PROPERTY struct and set the array value to the User Property count. We loop through that array and get the actual User Property by calling getUserPropertyByIndex(). We set the strings artistName and songName to the first two values of the userProperties array and use Debug.Log() to output this information in Unity’s console.

After that we start the instance (also immediately release it to free if from memory after playing to the end) and use a while loop to wait until the instance is stopped.

Once the instance is an stopped state, we clear the instance handle and wait until the instance in not valid anymore, in case this may take longer than necessary.

The initial for loop will advance to next song until all song played once. We call ShuffleMusic() again to re-shuffle our tracks. Insert ShuffleMusic() inside Unity’s Start() method so we can test the shuffle behaviour when starting the game.

Setup in Unity

Create a new GameObject and add the ShufflePlaylist component to it. Select the number of songs in the Size field and select your songs in the array element fields:

ShufflePlaylist script in Unity's inspector
ShufflePlaylist script in Unity’s inspector

Start the scene and look at Unity’s Console: you will see the songs displayed in a shuffled order, as well as the artist and song name:

Shuffled songs displayed in Unity's Console
Shuffled songs displayed in Unity’s Console

I visualized this information using a canvas and three text elements, including the current song time:

FMOD User Properties visualized in Unity
FMOD User Properties visualized in Unity

↑ To the Top