Как делают передвижение в онлайн играх?

введите сюда описание изображения

Мое понимание процесса передвижения в рамках Unity:

Частота обновлений в FixedUpdate очень мала для отображения плавной картинки, поэтому разумнее передвигать персонажа в Update.

Мы посылаем ввод серверу в одном из вызовов FixedUpdate. Сервер, обрабатывая пришедший ввод, передвигает у себя игрока на 1 условный метр. Но из за разницы частоты обновления сервера и клиента, клиент передвинет своего персонажа на 7 условных метров дальше (это число зависит от качества сети и нагруженности поцессора).

Суть вопроса

Где в моих рассуждения допущена ошибка? Как на самом деле делают передвижение в онлайн играх, ведь у War Thunder и World of Tanks частота обновлений всего-то 20-30 Гц?


Ответы (1 шт):

Автор решения: Maxgmer

Да, на сервере есть FPS (Update() на вашей диаграмме) и tick rate (аналог Fixed Update), который более редкий.

Поправлю некоторые утверждения:

Сервер, обрабатывая пришедший ввод, передвигает у себя игрока на 1 условный метр. Но из за разницы частоты обновления сервера и клиента, клиент передвинет своего персонажа на 7 условных метров дальше

Это утверждение неверно, т.к. все движения умножаются на время от кадра к кадру. Скажем, время между Update() - 0.25 сек, а между FixedUpdate() - 1 сек. Если скорость - 1 метр в секунду, то каждый Update() будет двигать персонажа на 1 * 0.25 метров, а каждый FixedUpdate() - на 1 * 1 метров в секунду. За 4 Update() получится то же самое, что и за 1 FixedUpdate(). Но все равно если бы на клиенте движение было в Update(), а на сервере - в FixedUpdate(), были бы небольшие, накапливающиеся расхождения, поэтому читаем дальше.

Частота обновлений в FixedUpdate очень мала для отображения плавной картинки, поэтому разумнее передвигать персонажа в Update.

Эта догадка логична, но работает все не так). Движение реально происходит в FixedUpdate() и на сервере, и на клиенте, но двигаемый объект никак не рисуется на экране. Вместо этого на клиенте есть отдельный "графический объект", который плавно следует за скачущим "реальным" объектом. Вот он обновляется в Update() чаще, создавая иллюзию плавности.

В одном ответе не поместить все детали синхронизации, надо читать соответствующие статьи, но к сути вопроса:

Tick Rate 20-30 гц - это очень много, не "всего-то" :)

Да, при 20 гц tick rate может быть задержка на ввод до 50 мс (в среднем в районе 25мс), но это очень незаметно. Когда, благодаря интерполяции в Update(), про которую я упомянул выше, визуально все выглядит очень плавно, очень сложно заметить 1-50 мс задержку на ввод.

→ Ссылка