- Home /
Strange AudioSource issue, hogging resources
Hi all,
I've been doing the Project Stealth tutorial project again, and for the majority of the tutorials it was fine. However when I finished adding the AI, and came to play test there has been an odd issue.
When the alarm goes off, the sirens do not play the audio they have been assigned, the audio stutters horribly and hogs system resources. FPS drops dramatically.
Here is a video of it occurring: https://dl.dropboxusercontent.com/u/44903480/Unity%20Problem/Problem.mp4
I'll also attatch the C# script that manages this aspect of the game.
using UnityEngine;
using System.Collections;
public class LastPlayerSighting : MonoBehaviour
{
//Data members -----------------------------------------
// A position the player could not theoretically reach. When this variable has these values, the enemies are unaware of the player
public Vector3 position = new Vector3(1000, 1000, 1000);
// The reset position, used to make enemies lose the player
public Vector3 resetPosition = new Vector3(1000, 1000, 1000);
public float lightHighIntensity = 0.25f; // High Intensity of the light
public float lightLowIntensity = 0f; // Low intensity of the light
public float fadeSpeed = 7f; // Light fade speed
public float musicFadeSpeed = 1f; // Music fade speed
// Volume variables used for Lerping the two audio sources. This is more efficient than using 3 billion conditional statements
public float panicVolume; // Volume of the panic music
public float normalVolume; // Volume of the normal music.
// Private variables storing references to other game objects and components
private AlarmLight alarmLight;
private Light mainLight;
private AudioSource panicMusic;
private AudioSource[] sirens;
//End Data members -------------------------------------
//Methods ------------------------------------------------------------------------------
//------------------------------------------------------
void Awake()
{
// This function is essentially a constructor, it runs when the object has loaded, or "woken up"
// Reference for the alarm light, and the main light. These will be used for the "pulsing" when the player has been detected.
alarmLight = GameObject.FindGameObjectWithTag(Tags.alarm).GetComponent<AlarmLight>();
mainLight = GameObject.FindGameObjectWithTag(Tags.mainLight).light;
// The music will change when the player has been detected to a more dramatic, "paniced" music
panicMusic = transform.Find("secondary_music").audio;
// The sirens around the map will be stored in an array. First we must find all of the siren objects and store a reference to them
GameObject[] sirenGameObjects = GameObject.FindGameObjectsWithTag(Tags.siren);
// and then store references to the audio sources in those game objects.
sirens = new AudioSource[sirenGameObjects.Length];
for(int i = 0; i < sirens.Length; i++)
{
sirens[i] = sirenGameObjects[i].audio;
}
}
//------------------------------------------------------
void Update()
{
SwitchAlarms ();
MusicFading();
}
//------------------------------------------------------
void SwitchAlarms()
{
// Set the alarm on, for the lights
alarmLight.alarmOn = (position != resetPosition);
// A float to store the target intensity of the main light. Control of Alarm Light is done in AlarmLight.cs
float newIntensity;
// If the alarm is on, target intensity is low, otherwise it is high.
if(alarmLight.alarmOn)
{
newIntensity = lightLowIntensity;
}
else
{
newIntensity = lightHighIntensity;
}
// Lerp the main light's intensity from current to target
mainLight.intensity = Mathf.Lerp (mainLight.intensity, newIntensity, fadeSpeed * Time.deltaTime);
for(int i = 0; i < sirens.Length; i++) // Loop through all of the siren game object's audio components.
{
if(alarmLight.alarmOn && !sirens[i].isPlaying)
{
sirens[i].Play();
}
else if(!alarmLight.alarmOn)
{
sirens[i].Stop();
}
}
}
//------------------------------------------------------
void MusicFading()
{
// Adjust the volume of the two audio sources, depending on whether or not the alarm has been triggered.
if(position != resetPosition)
{
panicVolume = 0.4f;
normalVolume = 0f;
}
else
{
panicVolume = 0f;
normalVolume = 0.4f;
}
audio.volume = Mathf.Lerp (audio.volume, normalVolume, musicFadeSpeed * Time.deltaTime);
panicMusic.volume = Mathf.Lerp (panicMusic.volume, panicVolume, musicFadeSpeed * Time.deltaTime);
}
//End Methods --------------------------------------------------------------------------
}
Answer by meat5000 · Jun 16, 2014 at 05:05 PM
void Update()
{
for(int i = 0; i < sirens.Length; i++)
{
//Stuff
}
}
At a glance, this is the essence of what is costing you.
Before you say it, yes I see its a separate function but as its executed every frame I wrote it as above.
So the for loop is the issue?
This is how it was done in the tutorial, and I can't see a more efficient way to make a group of objects emit a sound
As I say, at a glance. What I'm seeing is a potentially large for loop churning through each frame. Adjusting your AudioBuffer settings may remedy the jumps. But then I'm not sure how long sirens.Length is.
You may also have a problem with the way you are setting your volume. Again, every frame with the
if(position != resetPosition)
routine setting the volume then it being changed by the Lerp. Looks like it could potentially oscillate a bit.
sirens.Length is only 5, what changes would you recommend I make to the audio buffer?
I've found that the problem does not occur when I first load up Unity and test it in the editor, the problem occurs after I build the solution, and after that it happens in the editor also
Your answer
Follow this Question
Related Questions
What does the numSamples parameter in GetOutputData actually mean? 1 Answer
Help with Simple Footsteps? 2 Answers
Unity Unable to Reassign Audio Clip 1 Answer
Too many AudioSources? 1 Answer
GameObject reacts to audio source 1 Answer