WaitForSeconds 逐渐变得不同步...统一
WaitForSeconds Gradually become out of Sync... Unity
我正在为 google cardboard 创建节奏 VR 游戏,灵感来自 Beat Saber on PS VR 和 Oculus Rift。
概念是随着音乐的节奏,不同方向的方块向你袭来,就像 Beat Saber 中一样。
对于每首音乐,我都创建了一个名为 music 的 ScriptableObject,每个参数都应包含歌曲的难度、名称等,还有一个名为 notes 的 Vector3 数组:第一个Vector 的浮点数对应于从 0 开始的音乐节奏中音符应该被敲打的时间:ScriptableObject
然后在名为 SlashSpawnManagement 的脚本中,其中所有内容都基于 WaitForSeconds(),我生成要粉碎的方块。我真的很难用文字来解释我做的顺序,所以这是一张图片:Explanation
理论上,这个脚本做了什么,它等待一段时间,生成一个块,等待一段时间,生成一个块,等等。逻辑似乎没问题,但这是奇怪的部分。当您播放歌曲时,每个块之间的距离逐渐变得越来越大,这意味着块与音乐越来越不同步。开头很好,但是音乐结尾至少有5秒的间隔
我认为这与帧速率下降有关,所以我尝试将帧速率设置为较低的值:
QualitySettings.vSyncCount = 0; // VSync must be disabled
Application.targetFrameRate = 30;
但是并没有解决问题。我尝试使用 WaitForSecondsRealtime 而不是 WaitForSeconds,但没有任何变化。我在某处读到 WaitForSeconds 取决于帧速率......在我计算时间的地方,我尝试用 sustractng h 除以一个数字来平衡逐渐的差距。这适用于某些块,但不适用于每个块:Notes[j][0] - h / 500
所以这是我的问题,我如何使 WaitForSeconds 或与提供的秒数一致的任何其他方法?
提前致谢,
PS : 如需更多说明,请询问并请原谅我的错别字和英语:)
如果您希望某些事情定期发生,请务必确保错误不会累积。
不要:
private IEnumerable DoInIntervals()
{
while (this)
{
yield return new WaitForSeconds(1f); // this will NOT wait exactly 1 second but a few ms more. This error accumulates over time
DoSomething();
}
}
做:
private IEnumerable DoInIntervals()
{
const float interval = 1f;
float nextEventTime = Time.time + interval;
while (this)
{
if (Time.time >= nextEventTime)
{
nextEventTime += interval; // this ensures that nextEventTime is exactly (interval) seconds after the previous nextEventTime. Errors are not accumulated.
DoSomething();
}
yield return null;
}
}
这将确保您的活动定期举行。
注意:尽管这将是常规的,但不能保证它会与音频等其他系统保持同步。这只能通过在系统之间共享时间来实现,就像 spender 在他对你的问题的评论中提到的那样。
尝试使用 WaitForSeconds 音频计时并希望最好是希望很大。
提前准备好Vector3的列表。如果您想使用节奏准备列表 - 它会起作用。使用AudioSource的time检查每个Update的时机是否正确,并在那个时刻产生一个块。
void Update () {
SpawnIfTimingIsRight();
}
void SpawnIfTimingIsRight() {
float nextTiming = timingsArray[nextIndex].x;
// Time For Block To Get To Position
float blockTime = this.blockDistanceToTravel / this.blockSpeed;
float timeToSpawnBlock = nextTiming - blockTime;
if (this.audioSource.time >= nextTiming && (this.audioSource.time - Time.deltaTime) < nextTiming) {
// Spawn block
}
}
我正在为 google cardboard 创建节奏 VR 游戏,灵感来自 Beat Saber on PS VR 和 Oculus Rift。
概念是随着音乐的节奏,不同方向的方块向你袭来,就像 Beat Saber 中一样。 对于每首音乐,我都创建了一个名为 music 的 ScriptableObject,每个参数都应包含歌曲的难度、名称等,还有一个名为 notes 的 Vector3 数组:第一个Vector 的浮点数对应于从 0 开始的音乐节奏中音符应该被敲打的时间:ScriptableObject
然后在名为 SlashSpawnManagement 的脚本中,其中所有内容都基于 WaitForSeconds(),我生成要粉碎的方块。我真的很难用文字来解释我做的顺序,所以这是一张图片:Explanation
理论上,这个脚本做了什么,它等待一段时间,生成一个块,等待一段时间,生成一个块,等等。逻辑似乎没问题,但这是奇怪的部分。当您播放歌曲时,每个块之间的距离逐渐变得越来越大,这意味着块与音乐越来越不同步。开头很好,但是音乐结尾至少有5秒的间隔
我认为这与帧速率下降有关,所以我尝试将帧速率设置为较低的值:
QualitySettings.vSyncCount = 0; // VSync must be disabled
Application.targetFrameRate = 30;
但是并没有解决问题。我尝试使用 WaitForSecondsRealtime 而不是 WaitForSeconds,但没有任何变化。我在某处读到 WaitForSeconds 取决于帧速率......在我计算时间的地方,我尝试用 sustractng h 除以一个数字来平衡逐渐的差距。这适用于某些块,但不适用于每个块:Notes[j][0] - h / 500
所以这是我的问题,我如何使 WaitForSeconds 或与提供的秒数一致的任何其他方法?
提前致谢,
PS : 如需更多说明,请询问并请原谅我的错别字和英语:)
如果您希望某些事情定期发生,请务必确保错误不会累积。
不要:
private IEnumerable DoInIntervals()
{
while (this)
{
yield return new WaitForSeconds(1f); // this will NOT wait exactly 1 second but a few ms more. This error accumulates over time
DoSomething();
}
}
做:
private IEnumerable DoInIntervals()
{
const float interval = 1f;
float nextEventTime = Time.time + interval;
while (this)
{
if (Time.time >= nextEventTime)
{
nextEventTime += interval; // this ensures that nextEventTime is exactly (interval) seconds after the previous nextEventTime. Errors are not accumulated.
DoSomething();
}
yield return null;
}
}
这将确保您的活动定期举行。
注意:尽管这将是常规的,但不能保证它会与音频等其他系统保持同步。这只能通过在系统之间共享时间来实现,就像 spender 在他对你的问题的评论中提到的那样。
尝试使用 WaitForSeconds 音频计时并希望最好是希望很大。
提前准备好Vector3的列表。如果您想使用节奏准备列表 - 它会起作用。使用AudioSource的time检查每个Update的时机是否正确,并在那个时刻产生一个块。
void Update () {
SpawnIfTimingIsRight();
}
void SpawnIfTimingIsRight() {
float nextTiming = timingsArray[nextIndex].x;
// Time For Block To Get To Position
float blockTime = this.blockDistanceToTravel / this.blockSpeed;
float timeToSpawnBlock = nextTiming - blockTime;
if (this.audioSource.time >= nextTiming && (this.audioSource.time - Time.deltaTime) < nextTiming) {
// Spawn block
}
}