Devlog 2 / FMOD/Unity

So second developer diary is here, this time focusing on FMOD. My top priority currently is updating Look Out Below! for its free and multi-platform release. The game has sold abysmally but covered its tiny costs and I’m at the point now where I don’t care too much how it sells (I’m lying… I wish it sold better). I’ve learn’t a lot since we started the project and now I know that there are things that could be done better that I want to patch up before it goes free where there will be a lot more people (I hope) who try it out, so these updates are for them and me.

Ramble over! on to FMOD/Unity

Firelight Technologies made there product FMOD and FMOD Studio FREE for indie developers who’s budget is less that $100,000. I’ve been aware of FMOD for a long time, the logo used to show up along side the developers and publishers on AAA games opening splash screens so when they made it free along with Unity integration I couldn’t wait to try out this AAA product in indie context of Look Out Below!, and since its an android game and plugins for android don’t require Unity Pro we could use it straight away in the indie version, so it’s ENTIRELY free…… I think.

FMOD Studio is where all the setup happens, you assemble your sounds, effects and sequences in it and in the end produce a series of bank files. For me this is perfect as it means that should we suddenly jump ship with Unity, which is unlikely but who knows, we can just pick up our audio and use it in whatever engine we move to.

I’m going to run through exactly how we updated Look Out Below! from our in house audio manager to FMOD which took maybe a few hours but overall was a pretty painless procedure.

So first off I created a new FMOD project, when you start a new project it look like this;

Breaking down this interface we have the Events, Editor and Properties windows.

The Events window is a folder structure where you create “Events” made up from 1 or more audio clips, which will later be called from your code. The Editor window shows a timeline for your selected event allowing you to visualize your audio clips and create behaviors for it and the Properties window allows you to make tweaks and behaviors (like pitch adjustment) for your clips. There’s a lot more that can be done, ‘Event sounds’ allow you to have ‘Sub events’ which adds a maddening amount of flexibility, but I’ll go into that later.

So with that set up I added all the audio clips Look Out Below! uses by openinging up the Audio Bin (Ctrl + 3) and drag/dropping from my Audio folder in the Unity project.

I then started making events, which for the most part was 1 event for every clip but in a more in depth game I would imagine there being more clip variations, to create an event just right click the events window and click “New Event”, I grouped the events by their type of event also. Most of the events in Look Out Below! are single clips at the start of the timeline with no special behaviour. You can see the clip in the timeline and preview it.

The engine noise needed to loop and play continuously so to that event I added a “Loop Region” by right clicking in the black bar between the audio track and the play button, when the pin enters a loop region it will stay there and loop over the selected area of sound.

For these types of event calling them from unity is fairly simple, here’s the code I’m using;

using UnityEngine;
using System.Collections;

public class DroppableItem : MonoBehaviour{
	FMOD.Studio.EventInstance dropAudio;

	void Awake()
	{
		dropAudio = FMOD_StudioSystem.instance.GetEvent("event:/Dropping/"+dropSound);
	}

	void PlayAudio()
	{
		dropAudio.start();
	}
}

That’s about as complicated as the behaviors go for the effects, but the music had a more interesting behavior. We needed the music to fade out when going form the main menu to a level, and in the level pick a random song from our in game music list.

Here’s how the Music event looked

FMODMusicEvent

So what do we have here? so when the event starts if goes straight into the main menu Event sound, while the pin is in an event sound it continues to play, so at 1 bar in it goes into a small loop region, because its looping in an event sound it doesn’t loop over the same part of the track, it instead just continues to play the sound like a normal song, actually inside that event sound there is a loop region of the whole main menu song, so while the pin is over this event the song plays fully and repeats. FMOD lets you define parameters that can be used for many many uses but here I have 1 parameter called “MainMenu”, a float value between 0 and 1 which I control from within Unity to enter and exit the main menu song. Inside this loop I have a “transition to” point (the yellow/green arrow) which will move the pin to the “MainMenuExit” point when the “MainMenu” parameter equals 0. Using this I can break out of the main menu loop and let the pin move forward. The pin then continues from the “MainMenuExit” point to the “To InGame” transition point which jumps the pin to the “InGame” Event sound, which looks like this;

InGameEventSound

This is a Multi Sound Event, which randomly picks a sound from the list of audio, which for Look Out Below! is our 3 music tracks, so basically when the pin enters this event it starts playing one of the tunes. Finally, from within unity when I set the “MainMenu” parameter to 1 again it triggers tge “To InGameExit” transition point, which fades out the InGame music and jumps back to the “MainMenu” track. he behaviours not overly complex but it shows the immense flexibility of FMOD Studio.

The code to switch between MainMenu and InGame looked like this, the functions were mostly called from our GameLevelManager class…. mostly;

public class MainMenuMusic : MonoBehaviour {
	
	static FMOD.Studio.EventInstance music;
	static FMOD.Studio.ParameterInstance mainMenu;
	
	void Start () {
		//Set music to main menu
		music = FMOD_StudioSystem.instance.GetEvent("event:/Music/Music");
		music.start();
		music.getParameter("MainMenu", out mainMenu);
		SetMainMenu (true);
	}
	

	public static void SetMainMenu(bool arg){
		mainMenu.setValue (arg ? 1f : 0f);
	}
}

The last thing to implement was our music options. In the options screen of Look Out Below! the player can turn off the music, effects or both, to do this I had to create a sound bus for each of these. Creating the buses is pretty easy, Ctrl+2 opens the Mixer window, and fom here you can create buses then drag and drop the events into them. I created 2 buses, “Music” and “Sound”, and dragged the appropriate events into each.

FMODBuses

To enable or disable the tracks I was simply changing the volume of each bus;

public class MusicOptionsManager : MonoBehaviour {
	
	const float defaultMusicVolume = 0.42f;

	static FMOD.Studio.MixerStrip musicBus;
	static FMOD.Studio.MixerStrip soundBus;

	void Start () {
		FMOD.GUID guid;
		FMOD.Studio.System system = FMOD_StudioSystem.instance.System;

		//Get the music bus
		system.lookupID("bus:/Music", out guid);
		system.getMixerStrip(guid, FMOD.Studio.LOADING_MODE.BEGIN_NOW, out musicBus);

		//Get the sound bus
		system.lookupID("bus:/Sound", out guid);
		system.getMixerStrip(guid, FMOD.Studio.LOADING_MODE.BEGIN_NOW, out soundBus);

		ApplyMusicOption();
		ApplySoundOption();
	}
	
	public static void ApplyMusicOption()
	{
		musicBus.setFaderLevel(MusicOptions.music ? defaultMusicVolume : 0f);
	}
	
	public static void ApplySoundOption()
	{
		soundBus.setFaderLevel (MusicOptions.sound ? 1f : 0f);
	}
}

Where the MusicOptions class is just something that saves a loads the preferences as bools using PlayerPrefs.

Right so that’s about everything covered, the FMOD Unity integration still seems like its slightly under development so I can imagine some of this being subject to change but at the time of writing it’s how it all works. I know I’ve been quite disorganized with this blog but hopefully someone will find this useful, I’m still getting into this whole blogging thing. FMOD have a great product and I highly recommend it to all Unity developers, extra thanks to Anastasia Devana whose awesome tutorial really helped with getting to grips woth the whole system.

2 Comments

  • Lewis Bean Says

    hey great article though been trying out the code you gave with the blog and a cannot get anything to play even from the first example and I suppose to add a event emitter or … ?

    thanks for the help in advance

    Lewis

    • Mark Says

      Ah yeah in that first code snippets the PlayAudio() method was called from within a bigger Drop() method that I didn’t include. You could call it in Start() or OnTriggerEnter() to test it

Leave a comment

Your email address will not be published.