3

我的游戏中有暴风雨,所以我制作了一个环境音频文件,它慢慢地变成暴风雨并逐渐消失,然后变成一个可循环的暴风雨音频文件。以下是我的做法:

// 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 开始。这有点工作,但不是真的,因为两者之间偶尔会有差距。那么我该怎么做才能使过渡无缝呢?

4

6 回答 6

2

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

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

于 2013-11-04T09:50:37.413 回答
2

我现在正在为 Unity 开发音乐中间件,我经常遇到这个问题。这些“间隙”的出现只是因为 Unity 需要在播放之前从光盘加载音频数据,所以它不能真正立即播放。如果您想安排一些音频剪辑在特定时间播放,您需要提前了解它,您需要使用 AudioSource.PlayScheduled,正如@Kay 建议的那样。

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

但是,如果您尝试手动循环播放剪辑,并在同一位置一遍又一遍地启动它,您将再次遇到间隙。它们会短得多,你可能无法注意到它们,但它们会在那里——你可以通过录制音频输出并在一些音频编辑器中查看来检查它们。为了摆脱这种情况,我使用具有相同剪辑的音频源并一个接一个地启动。

于 2013-11-05T08:55:55.457 回答
1

莱克说的是事实。

我不知道怎么做,我不知道为什么,但 Unity 仅支持来自 Wavosaur 的 Wav 循环点。我从来没有让它在其他软件上工作,比如 fl studio 或 audacity。

在 Wavosaur 中打开您的声音,选择您要循环播放的区域,然后单击“L”红色图标。就是这样,声音将按照您的循环点在 Unity 中循环播放。

遗憾的是,Unity 没有记录/增强这个有用的特性。

于 2022-02-02T14:20:11.783 回答
0

UNITY 支持 WAV 循环点元数据。

让我再说一遍,因为我已经无缘无故地破坏了我的神经元 2 年:

UNITY 支持 WAV 循环点元数据。

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

于 2018-12-26T16:49:44.763 回答
0

我知道这很旧,但我想免费分享我的 IntroLoop 课程!默认情况下,此类从头开始播放文件,从 introBoundary 循环到 loopBoundary 就像 5argon 的一样。我添加了一些新功能,编码时间: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
/* **************************************************** */
于 2019-02-03T16:43:00.040 回答
-1

我制作了一个名为 Introloop 的解决方案,它是一个 Unity 插件,您可以播放带有前奏部分的 BGM,该部分进入无限循环,而无需将文件切割成 2 个剪辑。

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

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

于 2016-01-08T12:18:30.423 回答