有FMOD经验的人可以阻止我失去它。我无法让这些同步点正常运行。我有一些游戏音乐,由两部分组成,一个介绍和一个循环。它们是独立的声音,在前奏结束后,它开始循环部分,永远重复。我在介绍的末尾设置了一个同步点来触发循环。它工作得很好,直到我尝试停止并重新启动音乐(例如当播放器死亡时)。无论如何,同步点坚持在 intro 重新启动后立即触发,即使它已设置为 intro 结束。效果是音乐的两个部分同时播放 - 似乎在一个频道上,因为我告诉它重用频道。这甚至可能吗?这是我的一些代码(注意系统、介绍、循环和通道是成员变量):
public void Play()
{
if (intro != null)
{
CHANNELINDEX index = (channel == null) ? CHANNELINDEX.FREE : CHANNELINDEX.REUSE;
system.playSound(index, intro, false, ref channel);
uint length = 0;
intro.getLength(ref length, TIMEUNIT.MS);
intro.addSyncPoint(length, TIMEUNIT.MS, "StartLoop", ref loopPtr);
channel.setCallback(callback);
}
else system.playSound(CHANNELINDEX.FREE, loop, false, ref channel);
Playing = true;
}
这是同步点:
private FMOD.RESULT SyncCallback(IntPtr c, CHANNEL_CALLBACKTYPE type, IntPtr a, IntPtr b)
{
if (Playing)
{
RESULT result = intro.getSyncPoint(0, ref loopPtr);
intro.deleteSyncPoint(loopPtr);
system.playSound(CHANNELINDEX.REUSE, loop, false, ref channel);
}
return RESULT.OK;
}
至少,这是回调的一个版本。我已经尝试了大约 20 个人。请注意,我告诉它删除同步点 - 当我检查返回时它是好的。为了以防万一,我也尝试了 loop.deleteSyncPoint。我还对其进行了 getsyncpointinfo 以确保触发的是我的 StartLoop 同步点。然而,当再次调用 play 时,它仍然会触发,在调用 stop 之后:
public void Stop()
{
Playing = false;
if (intro != null && loopPtr != IntPtr.Zero)
{
IntPtr ptr = IntPtr.Zero;
RESULT result = intro.getSyncPoint(0, ref ptr);
result = intro.deleteSyncPoint(ptr);
result = intro.getSyncPoint(0, ref ptr);
loopPtr = IntPtr.Zero;
}
channel.stop();
channel.setPosition(0, TIMEUNIT.MS);
}
请注意,Stop() 也尝试删除同步点,但它也没有这样做(即使结果返回 OK)。我尝试在停止时将通道位置设置为 0,这使情况变得更糟。在 deletesyncpoint() 调用之后,我在我的同步点中尝试了 channel.stop() ,但这导致了堆栈溢出,因为它在每次调用时继续调用同步点以停止,尽管尝试将其删除。我给它错误的指针还是什么?我已经尝试制作某种标志来表示不播放循环部分,但我不能,因为它会设置在 Play() 的中间,并且在 Play() 完成后立即调用同步点,在下次调用系统更新时。FMOD 坏了还是我遗漏了一些明显的东西?或者一些真正模糊和无证的东西......