Play sound on button click before loading level.

I've looked through most of the similar questions here, and tried different variations of my code, but I'm still unable to get it to work right.

Just to make it clear, I want a sound to be heard when I click my button before it loads to a level.

The code I'm currently using is:

var start : GUIStyle; 
var quite : GUIStyle;
var instruction : GUIStyle;
var history : GUIStyle;

var mySound : AudioClip;

function OnGUI ()
{
    if(GUI.Button (Rect(800,260,250,160),"",start))
    {
        audio.Play();
        if (!audio.isPlaying)
        {
        Application.LoadLevel ("Proj");
        }
    }

if(GUI.Button (Rect(250,600,240,130),"",quite))
{
    audio.Play();
    if (!audio.isPlaying)
    {
    Application.Quit ();
    }
}

if(GUI.Button (Rect(790,520,250,130),"",instruction))
{
    audio.Play();
    if (!audio.isPlaying)
    {
    Application.LoadLevel ("instruction");
    }
}

if(GUI.Button (Rect(240,270,290,140),"",history))
{
    audio.Play();
    if (!audio.isPlaying)
    {
    Application.LoadLevel ("History");
    }
}

}

This only allows an audio clip to be played upon clicking the button, but it doesn't load the respective levels. When I use this code:

if(GUI.Button (Rect(800,260,250,160),"",start))
{
    audio.Play();
    Application.LoadLevel ("Proj");
}

if(GUI.Button (Rect(250,600,240,130),"",quite))
{
    audio.Play();
    Application.Quit ();
}

if(GUI.Button (Rect(790,520,250,130),"",instruction))
{
    audio.Play();
    Application.LoadLevel ("instruction");
}

if(GUI.Button (Rect(240,270,290,140),"",history))
{
    audio.Play();
    Application.LoadLevel ("History");

The levels are loaded, but the audio clips are not played. Can anyone tell me where I went wrong?

Thank you!

I believe I found a better solution. If you look at the docs for PlayClipAtPoint, it says: “If you want further control over playback, you can use the following code instead.” The code is like this:

AudioSource PlayAudioClip(AudioClip clip, Vector3 position, float volume) {
    GameObject go = new GameObject("One shot audio");
    go.transform.position = position;
    AudioSource source = go.AddComponent<AudioSource>();
    source.clip = clip;
    source.volume = volume;
    source.Play();
    Destroy(go, clip.length);
    return source;
}

All you need to do to get the sound to keep playing when you load the level is call “Object.DontDestroyOnLoad(go)” before you return the AudioSource. I’ve tested it, and it solved the problem for me.

In your first example, the audio is playing when it gets to the check (before loading the level).

function OnGUI ()
{
    if(GUI.Button (Rect(800,260,250,160),"",start))
    {
        audio.Play();           // audio is told to play
        if (!audio.isPlaying)   // audio is now playing, so this does not execute
        {
        Application.LoadLevel ("Proj");
        }
    }

It only evaluates that !audio.isPlaying once, when the button is clicked.

You should use a Coroutine. For example:

function OnGUI ()
{
   if(GUI.Button (Rect(800,260,250,160),"",start))
   {
      StartLevel();
   }

and outside of the OnGUI function:

function StartLevel ()
{
   audio.Play();                    // play audio
   while (audio.isPlaying)          // while audio is playing,
   {
      yield;                        // chill out in here.
   }
   Application.LoadLevel ("Proj");  // then, continue on.
}

If there's anything you don't understand, please ask. Hope this helps!

yes, ideally something like this :)

yield WaitForSeconds(audio.length);
Application.LoadLevel("blah");