'How to have game audio loop at a certain point

I have a storm in my game, and so I've made an ambient audio file which slowly grows into a storm and rain fades in, which then becomes a loopable storm audio file. Here is how I've done it:

// Play intro clip and merge into main loop
var introTime = stormIntro.length;
AudioSource.PlayClipAtPoint( stormIntro, Vector3.zero, 0.7 );
Invoke( "StormMusic", introTime );

The way I'm currently trying to do it is get the length of the storm_intro audio clip, play the clip, and then invoke storm_loop to begin after the length of the intro has completed. This kinda works, but not really because there's occasionally a gap between the two. So how can I do it so the transition is seamless?



Solution 1:[1]

I guess the gap is because loading the StormMusic clip takes some time. So if you can trigger the intro manually for instance by a collider, AudioSource.PlayScheduled should do what you want.

Unfortunately there is no PlayQueued or CrossFade method available for audio sources like in animation.

Solution 2:[2]

What Lake says is truth.

I dont know how, i dont know why, but Unity support Wav loop points from Wavosaur only. I never get it to work from other software, like fl studio or audacity.

Open your sound in Wavosaur, select the area you want to loop and click the "L" red icon. Thats'it, the sound will loop in Unity following your looppoints.

It's a shame that Unity doesn't document/enhance this usefull feature.

Solution 3:[3]

UNITY SUPPORTS WAV LOOP POINTS METADATA.

Let me say this again, because I have been destroying my neurons for 2 years for absolutely no reason:

UNITY SUPPORTS WAV LOOP POINTS METADATA.

So get rid of those mp3s, set wav loop points with Wavosaur (free), and let Unity compress the wav into vorbis for you at import time.

Solution 4:[4]

I know this is old, but I wanted to share my IntroLoop class for free! By default, this class plays the file from the beginning, looping from introBoundary to loopBoundary just like 5argon's. I have added some new features, coding time: 30 minutes. One, you can play just a loop, no intro. Two, same as default but you can start anywhere not just at the beginning and still have and intro and a loop. and Three, you can play a the file from point a to b without looping by setting IntroLoop.playOnce to false after constructing the intro loop object. So now you can put all your audio into a single file.

example of use: After attaching your audio to the script's object, drag the audio component to a public field, and send into the constructor, You can make more than one IntroLoop object from the same audio file. This example will play an intro starting at the 5 second mark and loop from the 10 second mark to the 20 second mark:

//Example of use
//Construct
IntroLoop clip = new IntroLoop(audioSource,5f,10f,20f);
//no intro just loop
IntroLoop clip2 = new IntroLoop(audioSource,10f,20f,false);

//you can set it to play once
clip2.playOnce = true;    

//call to start
clip.start();

//call once a frame, this resets the loop if the time hits the loop boundary
//or stops playing if playOnce = true
clip.checkTime(); 

//call to stop
clip.stop();


/* **************************************************** */
//The Music IntroLoop Class handles looping music, and playing an intro to the loop
public class IntroLoop {
    private AudioSource source;
    private float startBoundary;
    private float introBoundary;
    private float loopBoundary;
    //set to play a clip once
    public bool playOnce = false;

    //play from start for intro
    public IntroLoop(AudioSource source, float introBoundary, float loopBoundary) {
        this.source = source;
        this.startBoundary = 0;
        this.introBoundary = introBoundary;
        this.loopBoundary = loopBoundary;
    }
    //play from start for intro or just loop
    public IntroLoop(AudioSource source, float introBoundary, float loopBoundary, bool playIntro) {
        this.source = source;
        this.startBoundary = playIntro?0:introBoundary;
        this.introBoundary = introBoundary;
        this.loopBoundary = loopBoundary;
    }
    //play from startBoundary for intro, then loop
    public IntroLoop(AudioSource source, float startBoundary, float introBoundary, float loopBoundary) {
        this.source = source;
        this.startBoundary = startBoundary;
        this.introBoundary = introBoundary;
        this.loopBoundary = loopBoundary;
    }
    //call to start
    public void start() { this.source.time = this.startBoundary; this.source.Play(); }
    //call every frame
    public void checkTime() {
        Debug.Log(this.source.time);
        if (this.source.time >= this.loopBoundary) {
            if (!this.playOnce) { this.source.time = introBoundary; }
        } 
    }
    //call to stop
    public void stop() { this.source.Stop(); }  
}
//The Music IntroLoop Class
/* **************************************************** */

Solution 5:[5]

I made a solution called Introloop, which is a Unity plugin that you can play BGM with intro section that goes into endless loop without cutting the file into 2 clips.

I used AudioSettings.dspTime related method like scheduling to ensure precise looping. And it supports cross fading between 2 intro-included audio also. You only have to provide it 2 time point per audio, and the script will handle the rest of audio juggling.

http://forum.unity3d.com/threads/378370/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kay
Solution 2 Unity Julibab
Solution 3 Eric Aya
Solution 4
Solution 5 5argon