如何在某个点上进行游戏音频循环

时间:2013-11-04 07:46:03

标签: unity3d audio playback

我的游戏中有风暴,所以我制作了一个环境音频文件,慢慢变成风暴和雨水,然后变成一个可循环的风暴音频文件。我是这样做的:

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

我目前正在尝试这样做的方法是获取storm_intro音频剪辑的长度,播放剪辑,然后调用storm_loop以在完成介绍的长度后开始。这个有点有效,但不是真的,因为两者之间偶尔会有差距。那么我怎么能这样做才能实现无缝过渡?

5 个答案:

答案 0 :(得分:2)

我想差距是因为加载 StormMusic 剪辑需要一些时间。因此,如果您可以手动触发介绍,例如碰撞器,AudioSource.PlayScheduled应该做你想要的。

不幸的是,没有 PlayQueued CrossFade 方法可用于动画等音频源。

答案 1 :(得分:2)

我正在为Unity制作音乐中间件,我经历了很多这个问题。这些“间隙”的出现只是因为Unity需要在播放之前从光盘加载音频数据,因此无法立即播放。如果你想安排一些音频片段在特定时间播放,你需要提前知道它,你需要使用AudioSource.PlayScheduled,正如@Kay所建议的那样。

您需要注意PlayScheduled不是在标准Time.time上运行,而是在AudioSettings.dspTime上运行。它永远不会暂停,甚至可以在编辑器中不同的游戏启动之间保持不变。因此,您需要编写audio.PlayScheduled( AudioSettings.dspTime + expectedDelay );之类的内容,以便在expectedDelay秒内播放某些音频片段。您需要将expectedDelay保持在合理的水平,以便Unity可以加载剪辑;数量取决于您的音频文件大小,导入设置,您正在优化的设备和其他内容;我想你可以在几次实验后得出正确的价值。

但如果您尝试手动循环剪辑,在同一位置反复启动剪辑,您将再次遇到差距。它们会更短,你可能无法注意到它们,但它们会在那里 - 您可以通过录制音频输出并在某些音频编辑器中查看它来进行检查。为了解决这个问题,我使用相同剪辑的音频源并一个接一个地启动。

答案 2 :(得分:0)

联合国支持WAV循环点元数据。

让我再说一遍,因为我完全没有理由破坏神经元已有2年了:

联合国支持WAV循环点元数据。

因此,摆脱掉这些mp3,使用Wavosaur(免费)设置wav循环点,并让Unity在导入时为您将wav压缩为vorbis。

答案 3 :(得分:0)

我知道这已经很老了,但是我想免费分享我的IntroLoop类! 默认情况下,此类从一开始就播放文件,就像5argon一样,从introBoundary循环到loopBoundary。我添加了一些新功能,编码时间:30分钟。 一,您可以玩一个循环,没有介绍。二,与默认值相同,但您不仅可以从头开始,还可以在任何地方开始,并且具有intro和循环。和三个,可以通过在构造intro循环对象之后将IntroLoop.playOnce设置为false来播放a点到b点的文件而不会循环。因此,现在您可以将所有音频放入一个文件中。

使用示例: 将音频附加到脚本的对象之后,将音频组件拖到公共字段中,然后发送到构造函数中,您可以从同一音频文件中制作多个IntroLoop对象。本示例将从5秒标记开始播放介绍,并从10秒标记循环到20秒标记:

//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
/* **************************************************** */

答案 4 :(得分:-1)

我制作了一个名为Introloop的解决方案,这是一个Unity插件,你可以播放BGM的介绍部分进入无限循环而不将文件切割成2个剪辑。

我使用AudioSettings.dspTime相关方法(如调度)来确保精确循环。它还支持2个介绍包含音频之间的交叉淡入淡出。你只需要为每个音频提供2个时间点,脚本将处理其余的音频杂耍。

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

相关问题