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