Подход к решению не точной системы воспроизведения - PullRequest
0 голосов
/ 07 февраля 2019

Пытаясь сделать точную систему воспроизведения в единстве и c #

Привет всем, я работаю над гоночной игрой, и я решил добавить систему воспроизведения, чтобы разрешить и "машину-призрак", изначально я записывал данные внекоторые события, такие как нажатие клавиши, но только запись этих данных во всех кадрах. Я управляю плавным воспроизведением, но все равно все в порядке, поскольку файл не очень большой, и воспроизведение работает, но проблема в том, что всегда есть небольшое изменение во времени, например, 0,1 секунды илиМаксимум 0,2, у меня есть список ключевых кадров, и в каждой позиции я записываю время, которое нужно показать, проблема в том, что, поскольку fps меняются, то не во всех сериях показываются одинаковые метки времени, тогда время победного кадра невсегда отображается так, что выигрышный кадр появляется в следующем обновлении немного позже, чем должно быть показано.Я использую C # и Unity на всякий случай, но я думаю, что это в основном не зависит от этого.Большое спасибо за любую подсказку, я был вокруг этой проблемы в течение некоторого времени

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

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

Когда вы записываете состояние автомобиля (положение, курс и т. Д.) На кадр, вам также необходимо записать временную метку (в данном случае, накапливающую * 1003).* с начала гонки должно хватить).

При воспроизведении найдите текущую метку времени и интерполируйте (т. е. Lerp) состояние автомобиля из записанных ограничивающих кадров.

Подсказки дляинтерполяция кадра:

class Snapshot {
    public float Timestamp;

    public Matrix4x4 Transform;  // As an example.  Put more data here.
}

private int PrevIndex = 0;

private List<Snapshot> Snapshots = (new List<Snapshot>()).OrderBy(m => m.Timestamp).ToList();

private float GetLerpFactor(float currentTimestamp) {

    if ( PrevIndex == Snapshots.Count - 1) 
        return 0; // Reached end of Snapshots

    while (currentTimestamp >= Snapshots[PrevIndex + 1].Timestamp)
        PrevIndex++; // move 'frame' forward

    var currentDelta = Mathf.Max(0f, currentTimestamp - Snapshots[PrevIndex].Timestamp);
    var fullDelta = Snapshots[PrevIndex + 1].Timestamp - Snapshots[PrevIndex].Timestamp;

    var lerpFactor = currentDelta / fullDelta;
    return lerpFactor;
}
0 голосов
/ 07 февраля 2019

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

Если вы действительно хотите воспроизвести те же входные данные, которые вы должны запуститьдве раздельные симуляции одновременно, поэтому физика и время «реальной» версии не влияют на «призрачную», скорее всего вам придется снова интерполировать выходные данные «призрачной» симуляции, чтобы выровнять ее с реальной (если вы не исправиливременные шаги).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...