Using Wwise with Unity? Need doppler? You’re welcome!

Using Wwise with Unity? Need doppler? You’re welcome!

Those of you using Wwise with Unity may have noticed that there is no support for doppler shift. This is pretty mental given that Unity’s basic audio system offers doppler straight out of the box, so there’s obviously some kind of shenanigans afoot which prevents Wwise from getting hold of the information it needs from Unity. Fear not – I’ve spent a few hours doing some keen amateur coding so that you don’t have to! Here’s a C# script based on OpenAL’s doppler implementation :)

The combination of Wwise and Unity offers an incredibly powerful and accessible pipeline which not only enables audio designers to implement events into the game all by themselves but, with a little bit of elementary programming knowledge, it even allows them to add new features. Vive la Revolution!

/* 
 * DOPPLER EFFECT C# SCRIPT FOR UNITY & WWISE
 * 
 * Add this to a game object and then pass through dopplerPitch to an RTPC in Wwise, then season to taste :)
 * Make sure to center your RTPC around 1.0 - dopplerPitch is a multiplier!
 * I'd recommend starting out with a range of 0.0 to 2.0, with 0.0 = -300 cents and 2.0 = +300 cents
 * Also, note that you may need to search for a different listener object - this is set up to find a First Person Controller...
 * 
 * Script created with TLC by Kenneth C M Young - www.AudBod.com - @kcmyoung
 */

using UnityEngine;
using System.Collections;

public class Doppler : MonoBehaviour {
	
	public float SpeedOfSound = 343.3f;
	public float DopplerFactor = 1.0f;

	Vector3 emitterLastPosition = Vector3.zero;
	Vector3 listenerLastPosition = Vector3.zero;
	
	// Update is called once per frame
	void FixedUpdate () {

		// get the player object handy for the rest of the script!
		var player = GameObject.Find("First Person Controller");

		// get velocity of source/emitter manually
		Vector3 emitterSpeed = (emitterLastPosition - transform.position) / Time.fixedDeltaTime;
		emitterLastPosition = transform.position;
	
		// get velocity of listener/player manually
		Vector3 listenerSpeed = (listenerLastPosition - player.transform.position) / Time.fixedDeltaTime;
		listenerLastPosition = player.transform.position;
		
		// do doppler calc - see http://i.imgur.com/h5BMRmr.png or http://redmine.spatdif.org/projects/spatdif/wiki/Doppler_Extension (OpenAL's implementation of doppler)
		var distance = (player.transform.position - transform.position); // source to listener vector
		var listenerRelativeSpeed = Vector3.Dot(distance, listenerSpeed) / distance.magnitude;
		var emitterRelativeSpeed = Vector3.Dot(distance, emitterSpeed) / distance.magnitude;
		listenerRelativeSpeed = Mathf.Min (listenerRelativeSpeed, (SpeedOfSound / DopplerFactor));
		emitterRelativeSpeed = Mathf.Min (emitterRelativeSpeed, (SpeedOfSound / DopplerFactor));
		var dopplerPitch = (SpeedOfSound + (listenerRelativeSpeed * DopplerFactor)) / (SpeedOfSound + (emitterRelativeSpeed * DopplerFactor));

		// pass the dopplerPitch through to an RTPC in Wwise (or do whatever you want with the value!)
		AkSoundEngine.SetRTPCValue ("DopplerParam", dopplerPitch); // "DopplerParam" is the name of the RTPC in the Wwise project :)

		// uncomment the line below to see the numbers that are being passed through so you can adjust your RTPC values if necessary.
		//Debug.Log (dopplerPitch);
		
	}
About Kenneth Young 21 Articles
Kenny is a multi-award winning freelance sound designer, composer, audio director and writer best known for his work on Knights & Bikes, LittleBigPlanet, Astro Bot Rescue Mission and Tearaway. You can read more of his writing here on GameSound.org or learn more about his work via his professional website, AudBod.com.