- Home /
Problem with audio after leaving pause menu
Hello,
A while ago someone on here helped me fix this script(below) for which I am very greatful, but we couldn't get the audio to resume from where it was when the pause menu was exited. The music just started over. Which wasn't much of a problem until now. The reason it is now is beacuse I have more sounds in there so when the pause menu is exited all the ingame sounds play. I believe it has something to do with the array of audio sources that is a private variable, but if I change that then I have a feeling they will not stop at all when the pause menu is entered. All I want is for the sounds to contiune to stop when paused but when unpaused they continue from where they left off, or not play until they are supposed to. How would I go about this? Does anyone have an example? This is the script im using.
var pause : boolean = false;
var clickTexture : ClickTexture[];
private var allAudioSources : AudioSource[];
function Awake()
{
EnableClick( false );
for( var i : int = 0; i < clickTexture.Length; i++ )
{
clickTexture[i].pauseScript = this;
}
allAudioSources = FindObjectsOfType(AudioSource) as AudioSource[];
}
function PauseAllAudio()
{
for(var audioS : AudioSource in allAudioSources)
{
audioS.Pause();
}
}
function ResumeAllAudio()
{
for(var audioS : AudioSource in allAudioSources)
{
audioS.Play();
}
}
function Update()
{
if(Input.GetKeyUp(KeyCode.Escape))
{
pause = !pause;
if(pause == true)
{
Time.timeScale = 0.0;
EnableClick( true );
PauseAllAudio();
}
else
{
Time.timeScale = 1.0;
EnableClick( false );
ResumeAllAudio();
}
}
}
function RunOption( str : String )
{
if( str == "quit" )
{
Time.timeScale = 1.0;
Application.LoadLevel("AliensMainMenu");
}
else if( str == "resume" )
{
Time.timeScale = 1.0;
EnableClick( false );
ResumeAllAudio();
}
}
function EnableClick( b : boolean )
{
for( var i : int = 0; i < clickTexture.Length; i++ )
{
clickTexture[i].Show(b);
}
}
Also I should mention that after I leave the pause menu and press "esc" to try and go back to it, it starts the music over again and doesn't pause until I press it one more time.
Answer by Chronos-L · Mar 17, 2013 at 04:30 AM
Read this first
ou can use AudioListener.pause to pause-resume audio. The answers and script below will work, but it will be overdoing it.
Overdid Answers/Scripts
I wrote a wrapper to control the basic flow of a audio (Play, Pause, Resume, Stop)
AudioPlayer Wrappper (CS)
/*using UnityEngine; using System.Collections;
[RequireComponent(typeof(AudioSource))]
public class AudioPlayer : MonoBehaviour {
private float time;
private bool canPlay;
//Testing code, should be deleted
void Update() {
if( Input.GetKeyDown(KeyCode.P) ) {
Pause ();
}
if( Input.GetKeyDown(KeyCode.O) ) {
Resume ();
}
}
void Stop() {
audio.Stop();
time = 0;
canPlay = false;
}
void Play() {
audio.Play();
time = 0;
canPlay = true;
}
void Pause() {
canPlay = audio.isPlaying;
time = audio.time;
audio.Stop();
}
void Resume() {
if( canPlay ) {
audio.Play();
audio.time = time;
}
}
}*/
AudioPlayer.js // Overdid Script
/*private var time : float;
private var canPlay : boolean;
function Stop() {
audio.Stop();
time = 0;
canPlay = false;
}
function Play() {
audio.Play();
time = 0;
canPlay = true;
}
function Pause() {
canPlay = audio.isPlaying;
time = audio.time;
audio.Stop();
}
function Resume() {
if( canPlay ) {
audio.Play();
audio.time = time;
}
}*/
How to use
You will have to attach this script to all your audio source. I have tested this with 3 types of audio: a 3 minute song, a looping short-loop audio, and a one-shot death-cry.
Explanation
used AudioSource.time to make the audio player resume-able. I grab the audio.time
right before it is Stop()
, if I do it after, I will always get 0 for the audio.time
. When I Resume()
, I Play()
the audio
and set the audio.time
to match the last time
I Pause()
.
I use a boolean
canPlay
to determine whether the audio (this is meant for the one-shot audio) should be played when it is Resume()
. I grab the audio.isPlaying
when I Pause()
. When the one-shot audio is not done playing yet, it will continue playing when I Resume()
.
Pause.js
#pragma strict
var pause : boolean = false;
var clickTexture : ClickTexture[];
//var allAudioSources : AudioPlayer[];
function Awake()
{
EnableClick( false );
for( var i : int = 0; i < clickTexture.Length; ++i )
clickTexture[i].pauseScript = this;
//allAudioSources = FindObjectsOfType(AudioPlayer) as AudioPlayer[];
}
function PauseAllAudio()
{
/*for(var audioS : AudioPlayer in allAudioSources) {
if( audioS != null ) {
audioS.Pause();
}
}*/
AudioListener.pause = true;
}
function ResumeAllAudio()
{
/*for(var audioS : AudioPlayer in allAudioSources) {
if( audioS != null ) {
audioS.Resume();
}
}*/
AudioListener.pause = false;
}
function Update()
{
if(Input.GetKeyUp(KeyCode.Escape))
{
//Super lazy one-liner
pause = !pause;
if(pause == true)
{
Time.timeScale = 0.0;
EnableClick( true );
PauseAllAudio();
}
else
{
Time.timeScale = 1.0;
EnableClick( false );
ResumeAllAudio();
}
}
}
function RunOption( str : String ) {
if( str == "quit" ) {
Application.LoadLevel("AliensMainMenu");
}
else if( str == "resume" ) {
pause = false;
Time.timeScale = 1.0;
EnableClick( false );
ResumeAllAudio();
}
}
function EnableClick( b : boolean ) {
for( var i : int = 0; i < clickTexture.Length; ++i )
clickTexture[i].Show(b);
}
ClickTexture.js
#pragma strict
var pauseScript : Pause;
var optionString : String;
function OnMouseEnter()
{
//change text color
guiTexture.color = Color.red;
}
function OnMouseExit()
{
//change text color
guiTexture.color = Color.white;
}
function OnMouseUp()
{
pauseScript.RunOption( optionString );
}
function Show( b : boolean ) {
this.enabled = b;
if( guiTexture ) {
guiTexture.enabled = b;
}
if( guiText ) {
guiText.enabled = b;
}
}
@serenfox, test it first before you integrate it into your code. I whip it up in a short while and test it with only 3 different audio.
If you are using this one, you should change your script like so:
...
private var allAudioSources : AudioPlayer[];
function Awake()
{
...
allAudioSources = FindObjectsOfType(AudioPlayer) as AudioPlayer[];
}
function PauseAllAudio()
{
for(var audioS : AudioPlayer in allAudioSources )
{
audioS.Pause();
}
}
function ResumeAllAudio()
{
for(var audioS : AudioPlayer in allAudioSources )
{
audioS.Resume();
}
}
function Update()
{
...
}
function RunOption( str : String )
{
...
}
function EnableClick( b : boolean )
{
...
}
Thank you for the reply, but I have a question. The first code that is in CS, am I supposed to attach that to my gameobject that has the audio source attached to it? Then access it with the second code which is JS? Can you access a CS script by a JS? Or is it just the javascript I modify and not even use the CS?
The first code that is in CS, am I supposed to attach that to my gameobject that has the audio source attached to it?
Yes
Then access it with the second code which is JS?
Yes
Can you access a CS script by a JS?
Yes. Look at this. However, it is dead easy to convert this script to JS
have edited my answer to put in a JS version.*
Or is it just the javascript I modify and not even use the CS?
Use the AudioPlayer script, and make the appropriate changes to your Pause script as well.
Again thank you for replying and explaining. I have made the changes but now I get this error: $$anonymous$$issingReferenceException: The object of type 'AudioPlayer' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.
on this line: canPlay = audio.isPlaying;
Also when I press the escape key after exiting the pause menu it restarts everythinbg again. is the escape key already used for something? Is that why its doing that?
Your answer
Follow this Question
Related Questions
how to pause and resume music after pausing game? 4 Answers
Audio keeps playing when paused 1 Answer
Pause and resume coroutine 1 Answer
Audio Issue 1 Answer