Gamasutra: The Art & Business of Making Gamesspacer
Advanced Audio Streaming in Unity
View All     RSS
October 25, 2014
arrowPress Releases
October 25, 2014
PR Newswire
View All

If you enjoy reading this site, you might also want to check out these UBM Tech sites:

Advanced Audio Streaming in Unity

June 6, 2013 Article Start Page 1 of 3 Next

In the midst of making a simple casual game as part of a personal jam, Ben Long and Fredrik Kaupang uncovered a great trick for streaming audio in Unity.

One of my favorite learning experiences is the game jam. I'm amazed how these events can teach you the entire spectrum of skills required in this industry. Where else can one get a feel for every aspect of game development in 48 hours?

The GGJ (Global Game Jam) should be mandatory for anyone interested in an industry career (including employees of larger studios). Aside from learning various disciplines, you get direct exposure to what a 'deadline' really is without the pressure of a multimillion dollar production. This becomes a time when creativity is the driving force, and good times are most certain to be had.

Recently, Fredrik Kaupang and I decided to dive right into development of a casual classic and complete it in one weekend. Although we missed the official GGJ event, it made sense to just run a marathon of our own. Since we live in different cities (Denver and Boston), everything happened entirely over Skype.           

With the Chinese New Year right around the corner (and the 2013 Year of the Water Snake rapidly approaching), we had a waterproof plan: Make a classic Snake Game in Unity and localize it for both English and Chinese markets! The idea was certainly influenced by my talk at GDC China and the culture shock of seeing Shanghai for the first time, not to mention a lifelong interest in Chinese philosophy, food and kung-fu movies.

We proceeded to capitalize on Unity's greatest strength, and set out to deploy our work on every platform possible. This article was almost a portmortem, since Snake Game was ported to iOS, Android, Kindle, and the Chrome Store. Unfortunately, platforms and their owners aren't too fond of developers writing detailed articles about the submission process. Instead of going broad, we'll narrow focus: for this article, we will focus on the sonic side of things.

Snake Game is light on audio, so I was able to step out of my sonic comfort zone and work on art, HTML, and even get up to speed on platform requirements. I've been known to enjoy Photoshop/Illustrator, so it made sense to try my hand at game art. As an audio professional, it's a fun change to work with visuals, even though my skillset there is less flexible. Luckily, we built a sprite-based game where each component (snake body, head, tail and food) is a mere 44 x 44 pixels, and a gameplay background of 640x480 for web. These are our current sprites as of v1.2:

Sure, they are crude, but there is something therapeutic about making pixel art. Coloring the giant blocks puts you in a meditative state, but also challenges you to think of the outcome. The time flew by as the sushi details improved, until finally I thought, "Okay! This might work!" It was a microscopic victory, so I posted the PSD to Dropbox and had Fredrik try a few before implementation. After Skype's file sharing became a hurricane of misplaced assets, the cloud-based sharing helped to bring a bit of organization. The pixel art world is deep, and next time I will try free tools like this one, which is built for the task.

Once the initial web version ready, it was time to connect it with the ancient Chinese belief, which insists that people have a zodiac animal sign, and a specific element. Instead of making a Dragon game, which wouldn't be relevant for 11 years, we decided to make a re-skinnable snake game using the five elements of wood, metal, fire, earth, and water. We built the core game with flexibility in mind -- and the potential to create different gameplay elements for each Chinese element. The first step was to have a unique soundscape for each element game, so the water has an ocean soundscape, the earth has a distant lawnmower, etc.

Since we were making multiple versions of this game, it needed a place to live on the web, so I grabbed and dove right in. Our goal was to get the web version stable and use it for porting to the various web app and mobile app stores.

Each of the six games has their own looping music track, which is an ambient soundscape and what I call "wallpaper music." When creating such pieces of music, I always start with a general theme that then goes through several revisions. This is a subtractive approach, where layers and parts get axed until the piece is not interfering with gameplay too much. 

Article Start Page 1 of 3 Next

Related Jobs

Red 5 Studios
Red 5 Studios — Orange County, California, United States

Graphics Programmer
Red 5 Studios
Red 5 Studios — Orange County, California, United States

Gameplay Programmer
Gearbox Software
Gearbox Software — Plano, Texas, United States

Server Programmer
Forio — San Francisco, California, United States

Web Application Developer Team Lead


David DeLizza
profile image
Hey Ben, nice article. I had a question, you were talking about the looping functions of .ogg. I'm aware that ogg will loop, but is it true that you can't actually set loop points? it will just loop front to back right? Beside the size, and decompression speed, what are the other perks to using .ogg?

Glen Joyner
profile image
In my experience, there are no loop point usages in Unity. For a game I made we had to use an intro file for a song and then have the loop track start within the right amount of time. Worked well, and should be even more easily doable that way with PlayScheduled(), but it's still a hindrance. I'd be curious to see what Ben found.

Matt Rix
profile image
Great post!

FYI, an alternative way to store your audio clip info would be something like this:

It works similarly to an enum, but with the data contained in the objects, so it's much less brittle.

With this approach you could easily set up your code to say SFXManager.PlayAudio(AudioClipType.SnakeEat);

Fredrik Kaupang
profile image
Hey Matt, for sure! It would most certainly be helpful to organize the various SFXs and other assets in similar systems. Especially if the project grew to 20+ SFXs and multiple audio tracks, it would be easier to manage and maintain.

Nice stuff on your Github btw!

Ben Long
profile image
Hi David, thanks! OGG is preferred to MP3 in sound quality too. Even at 96kbps, an OGG file sounds closer to the original than a 96kbps MP3.

I'm sure there are audio engines that could make it loop at special points, but even with the default front-to-back looping specs, it doesn't have that added space you get with the annoying MP3 loop problem. There are work arounds, but they detract heavily from the creative side of game audio.

Hayk Saakian
profile image
Is there any kind of caching involved here?

This sounds like a cool solution, but I wouldn't want to hit a server every time I open the app.

Lance Trahan
profile image
Same here, this method is excellent for getting changes expedited quickly in internal development, but if you had a popular game played by many, the bandwidth costs would ramp up fairly quickly if you had enough assets being streamed.

Some form of caching would take care of this issue and you could flip a flag on the server that tells the client when it needs to update its audio cache.

Fredrik Kaupang
profile image
Hey Hayk, no caching so far. It seems that the .NET framework has a suitable class (System.Web.Caching). Would certainly be interested in exploring the subject further, as it seems Unity has a function (WWW.LoadFromCacheOrDownload) to cache asset bundles. Then each file would have to be in a versioned asset bundle, which could be time consuming for composers and sound designers to create and deploy)

We could bundle the SFXs with the build and save one server side call per SFX, but we would have to compromise some audio quality or see the build size triple. The overall size of the build is about the same, but the end user only needs to download 528 kb to start playing the game, while the audio and SFXs are being streamed in the background.

Lance, you might have to ask Ben about the bandwidth costs, though I believe it'll have to scale to a pretty solid amount of traffic before we would see too much extra costs.

Michael Herring
profile image
"Unfortunately, platforms and their owners aren't too fond of developers writing detailed articles about the submission process."

...what? Outside of anything covered by an NDA, why would a platform developer have an issue with writing about their platform (and anyway, what could they possibly do)?

Yossarian King
profile image
Good explanation, thanks for sharing.

One minor thing -- your audio clip management would be simpler if you replace the separate arrays for each piece of information (AUDIO_NAMES, AUDIO_TYPES, etc.) with an array of structures (or classes, since Unity doesn't serialize structures). Doing it this way would make it more obvious which information goes with which clip.

Here's what this might look like in C#:
public class AudioClipInfo
public string AudioName;
public string AudioType;
public int StreamingPriority;
public float AudioVolume = 1.0f;

public AudioClipInfo[] audioClipInfo;

Ander Ferreras
profile image
/* 3D sound? true
Streaming? false
AudioType? .OGG */
ourClip = www.GetAudioClip (false, true, AudioType.OGGVORBIS) ;

is this right or a typo
does it mean to be like this

/* 3D sound? false // switched
Streaming? true //switched
AudioType? .OGG */
ourClip = www.GetAudioClip (false, true, AudioType.OGGVORBIS) ;

thanks again for simple article and yea Unity is a move in the right direction for the Industry

Josh Sutphin
profile image
One neat thing that's worth noting: when you use the WWW class to get an audio clip, you're not limited to just http:// URLs. You can also specify a URL with the file:// protocol in order to use this same method to pull audio from the local disk. You could use this method to allow users to load custom audio into a music game, for example, or to create a local version of your web-based workflow (where you can audition audio assets in a standalone build without re-making the build each time), or to load audio files asynchronously.