Waitforseconds постепенно рассинхронизируется ... unity

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


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

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

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


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

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

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


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

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

PS: Для получения дополнительных разъяснений, пожалуйста, извините за мои опечатки и мой английский :)

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

spender 31.10.2018 13:51
docs.unity3d.com/ScriptReference/AudioSettings-dspTime.html - истинный источник времени, когда дело касается звука.
spender 31.10.2018 13:59

@spender Большое спасибо.

FireGreeks 31.10.2018 14:46
2
3
303
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Не делайте этого:

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

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

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

это очень похоже на мои мысли. Хотя часы dsp могут немного отклоняться от Time.time, их нельзя будет измерить через несколько минут.

zambari 31.10.2018 14:42
Ответ принят как подходящий

Попытка использовать 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
    }
}

Конечно, друг.

DmitryoN 01.11.2018 03:54

Другие вопросы по теме