I’m working on an iPhone game where we don’t want positional sound. At the moment I can think of two approaches to this:
1 - Use mono sounds but make sure they play from the centre of the play area/viewport.
2 - Don’t worry about where the sound sources are positioned but force them to play in stereo.
Which approach would you recommend? I’m favouring the first because forcing audio clips to play in stereo appears to double the filesize and bitrate. Any advice is much appreciated.
Attach the sound to your camera, or use PlayAtClipPoint to play your audio at the position of the camera:
PlayClipAtPoint looks useful. I’ll try it out. Thanks.
One issue I have found with PlayClipAtPoint is that it uses similar functionality to PlayOneShot… which if there are any clips still playing when a new Scene loads you will get a crash… it appears to be a bug when the currently playing clip gets disposed for the new Scene.
I have a hack/slash fix for this which just has a smart manager that does a lot of the work for you… also provides a convenient way of controlling all aspects of the clip like (pitch)… this script can be expanded to make it much better.
Make sure you call the “Stop()” method when loading a new scene to ensure that all sounds which could be disposed are stopped before performing the load.
using System;
using System.Collections;
using UnityEngine;
internal class Audio2D : MonoBehaviour
{
private const int C_CHANNELS = 8;
private static AudioSource[] m_audio_players;
private static bool m_initialized = false;
private static void Initialize()
{
if (m_initialized)
throw new Exception("System already initialized!");
GameObject listener = new GameObject("Audio2D");
listener.transform.position = Vector3.zero;
listener.AddComponent(typeof(AudioListener));
m_audio_players = new AudioSource[C_CHANNELS];
for (int i = 0; i < C_CHANNELS; i++)
{
GameObject go = new GameObject(string.Format("Audio2D_Channel{0}", i));
go.transform.position = Vector3.zero;
go.transform.parent = listener.transform;
m_audio_players[i] = (AudioSource)go.AddComponent(typeof(AudioSource));
}
Application.DontDestroyOnLoad(listener);
m_initialized = true;
}
private static AudioSource GetFreeChannel()
{
for (int i = 0; i < C_CHANNELS; i++)
{
if (!m_audio_players[i].isPlaying)
return m_audio_players[i];
}
return null;
}
public static void Play(AudioClip clip)
{
Play(clip, 1, 1);
}
public static void Play(AudioClip clip, float volume)
{
Play(clip, volume, 1);
}
public static void Play(AudioClip clip, float volume, float pitch)
{
if (!m_initialized) Initialize();
AudioSource channel = GetFreeChannel();
if (channel != null)
{
channel.volume = volume;
channel.pitch = pitch;
channel.clip = clip;
channel.Play();
}
}
public static void Stop()
{
if (!m_initialized) Initialize();
for (int i = 0; i < C_CHANNELS; i++)
{
if (m_audio_players[i].isPlaying)
m_audio_players[i].Stop();
m_audio_players[i].clip = null;
}
}
}
Did this get reported as a bug? If Unity is crashing because of audio playback, they need to know about it 