WaitForSeconds постепенно теряет синхронизацию ... Unity - PullRequest
0 голосов
/ 31 октября 2018

Я создаю виртуальную VR-игру для картона Google, вдохновленную Удар Сабля для PSVR и Oculus Rift.


Концепция заключается в том, что блоки с разными направлениями приходят на вас, следуя ритму музыки, как в Удар Сабля . Для каждой музыки я создал ScriptableObject , называемый музыкой, с каждым параметром, который он должен содержать, например, сложность песни, название и т. Д., А также массив Vector3, называемый примечаниями: первый всплеск вектора соответствует времени, когда нота должна быть разбита в ритме музыки, начиная с 0: ScriptableObject

Затем в скрипте с именем SlashSpawnManagement , где все основано на WaitForSeconds (), я порождаю блоки, чтобы разбить. Мне очень сложно объяснить словами, в каком порядке я это делаю, поэтому вот изображение: Объяснение

Теоретически, что делает этот скрипт, он ждет некоторое время, порождает блок, ждет некоторое время, порождает блок и т. Д. Логика кажется нормальной, но вот странная часть . Когда вы играете песню, расстояние между каждым блоком постепенно становится все больше и больше, а это означает, что блоки все больше и больше не синхронизируются с музыкой. Все начинается очень хорошо, но в конце музыки есть разрыв не менее 5 с.


Я подумал, что это как-то связано с падением частоты кадров, поэтому я попытался установить frameRate на что-то низкое с:

QualitySettings.vSyncCount = 0;  // VSync must be disabled
Application.targetFrameRate = 30;

Но это не решает проблему. Я попытался с WaitForSecondsRealtime вместо WaitForSeconds , но ничего не изменилось. Я где-то читал, что WaitForSeconds зависит от частоты кадров ... Там, где я рассчитывал время, я пытался sustractng h, деленный на число, чтобы выровнять постепенный разрыв. Это работает для некоторых блоков, но не для каждого блока: Notes[j][0] - h / 500


Так вот мой вопрос, как мне сделать WaitForSeconds или любой другой метод в соответствии с предоставленными секундами?

Заранее спасибо,

PS: За более подробной информацией, пожалуйста, спросите и, пожалуйста, прости мои опечатки и мой английский:)

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Попытка использовать WaitForSeconds определяет время аудио, и надежда на лучшее - большая надежда.

Подготовьте список Vector3 заранее. Если вы хотите подготовить список с помощью ритма - это сработает. Используйте время AudioSource, чтобы проверять каждое обновление на правильность времени и порождать блок в этот момент.

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
    }
}
0 голосов
/ 31 октября 2018

Если вы хотите, чтобы что-то происходило через регулярные промежутки времени, важно убедиться, что ошибки не накапливаются.

Не

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();
    }
}

Do:

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;
    }
}

Это обеспечит регулярность ваших событий.

Примечание. Несмотря на то, что это будет регулярно, это не гарантирует, что оно будет синхронизировано с другими системами, такими как аудио. Это может быть достигнуто только при наличии общего времени между системами, как упомянул спонсор в своем комментарии к вашему вопросу.

...