Образец, который вы связали, напрямую устанавливает позицию для того, что он получает из сети, это плохая идея для многопользовательской игры!
Что вы должны сделать в реальной игре, это интерполировать между локальной позицией иудаленная позиция.Итак, ваш метод приема будет выглядеть примерно так:
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
}
Затем вы отображаете «локальное» положение устройства, это обеспечивает движение без задержек следующим образом:
- Если положение устройства почти в удаленном положении, он переместится в удаленную позицию (однако он прыгнет на такое маленькое расстояние, что не будет выглядеть запаздывающим).
- Если разница слишком велика, чтобы прыгать, медленно двигайтесь к позиции, которую вы должныбыть внутри.
Поскольку устройство плавно движется туда, где и должно быть, похоже, что никакой задержки нет вообще!
Константа интерполяции контролирует, как быстро локальные и удаленные позициибудет сходиться: - 0: игнорировать обновления сети - малый: очень быстро защелкнуться на месте (возможно, он выглядит запаздывающим) - большой: медленно сдвинуться на место, выглядит гладким, но может не отвечать на запросыnsive
Вам нужно выбрать компромисс где-то между этими опциями.
Есть некоторые другие вещи, которые следует учитывать при реализации такого рода системы, например, вам часто требуется верхний предел того, как далекоОтдельно стоящие устройства могут находиться в удаленном положении, в противном случае местное и удаленное состояние в некоторых ситуациях может «отклеиться».Если они находятся слишком далеко друг от друга (что никогда не должно происходить, за исключением случаев крайней задержки), вы можете либо остановить игру и сказать пользователю, что она слишком запаздывает, либо перепрыгнуть юнит прямо в положение, которое будет выглядеть запаздывающим, но по крайней мере игра будетпродолжить.
Приложение: перечитывая этот ответ, мне приходит в голову, что улучшение должно было бы отслеживать разницу во времени.Если вы знаете (примерно), какова задержка в системе, то вы знаете, что, когда вы получаете пакет с удаленной позицией, вы примерно знаете, как далеко в прошлом этот пакет.Если вы также отправите удаленную скорость, вы можете предсказать, где сейчас находится объект (при условии постоянной скорости).В некоторых играх разница между предполагаемым локальным состоянием и истинным удаленным состоянием может быть меньше, в других играх (где у вас много изменяющихся скоростей) это может ухудшить ситуацию.