我的游戏中有风暴,所以我制作了一个环境音频文件,慢慢变成风暴和雨水,然后变成一个可循环的风暴音频文件。我是这样做的:
// 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以在完成介绍的长度后开始。这个有点有效,但不是真的,因为两者之间偶尔会有差距。那么我怎么能这样做才能实现无缝过渡?
答案 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个时间点,脚本将处理其余的音频杂耍。