Подтвердить что ты не робот

Работа с задержкой в ​​XNA + lidgren

Я экспериментирую с lidgren в XNA, и у меня возникают некоторые проблемы с "задержкой".

Я загрузил их образец XNA и заметил, что даже их выборки отстают. Дело в том, что движение не является гладким с другой стороны, и я пробую это в локальной сети (на том же самом компьютере) не через Интернет.

Были ли какие-либо проблемы с негладким движением из-за отстающей связи с lidgren и XNA?

4b9b3361

Ответ 1

Образец, который вы связали напрямую, устанавливает позицию для всего, что он получает из сети, это плохая идея для многопользовательской игры!

В реальной игре вы должны интерполировать местное положение и удаленное положение. Итак, ваш метод получения будет выглядеть примерно так:

void Receive(packet)
{
    unit.RemoteX = packet.Read_X_Position();
    unit.RemoteY = packet.Read_Y_Position();
}

Это не влияет на локальную позицию на устройстве, вместо этого в вашем методе обновления (каждый кадр) вы перемещаете локальную позицию в направлении удаленной позиции:

void Interpolate(deltaTime)
{
    difference = unit.RemoteX - unit.LocalX
    if (difference < threshold)
        unit.LocalX = unit.RemoteX
    else
        unit.LocalX += difference * deltaTime * interpolation_constant
}

Затем вы отображаете "локальную" позицию юнита, это обеспечивает безостановочное движение следующим образом:

  1. Если положение устройства почти в удаленном положении, оно переместится в удаленное положение (однако оно прыгнет на такое маленькое расстояние, что не будет выглядеть замедленным).
  2. Если разница слишком велика, чтобы прыгать, медленно продвигайтесь к позиции, в которой вы должны быть.

Поскольку устройство плавно движется туда, где и должно быть, похоже, что никакой задержки нет!

Константа интерполяции контролирует, насколько быстро сойдутся локальные и удаленные позиции: - 0: игнорировать обновления сети - малый: очень быстро защелкнуться на месте (возможно, выглядит запаздывающим) - большой: медленно скользить на место, выглядит плавным, но может не реагировать

Вам нужно выбрать компромисс где-то между этими вариантами.

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

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

Ответ 2

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

Я использую ваш пример кода выше, и он работает хорошо (мне пришлось подстроить константу интерполяции выше 1, чтобы она выглядела гладко).

Я видел несколько примеров интерполяции, которые учитывают разницу во времени между текущим временем и меткой времени на полученном сообщении.

Я вижу, что этот код не использует разницу во времени, поэтому интерполяция займет столько времени, сколько потребуется, чтобы добраться до целевого значения (или, по крайней мере, в пределах порогового значения, чтобы затем привязать к позиции). Мой вопрос в том, есть ли какое-то преимущество для этого?

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