Назад к блогу

Как исправить Player Location Desync в UEFN и Unreal Engine Multiplayer

Опубликовано 27 февраля 2026 г.
Как исправить Player Location Desync в UEFN и Unreal Engine Multiplayer

Кошмар Multiplayer Transform Desync

Каждый разработчик мультиплеерных игр рано или поздно сталкивается с моментом, когда netcode начинает ему врать. Вы пишете скрипт, где игрок садится в кресло, кресло движется по карте, и на сервере все выглядит идеально. Но когда вы заходите со второго клиента, иллюзия рушится. Клиент А видит себя идеально сидящим в кресле. Клиент B видит, как кресло уезжает, а Клиент А остается висеть в воздухе в точке старта.

Этот феномен — uefn player location desync — известная проблема при использовании player inputs для вызова команд MoveTo на пропах с прикрепленными (attached) игроками. Сервер регистрирует верное абсолютное местоположение, но simulated proxies (копии игрока на других клиентах) не наследуют обновленный transform от родительского пропа.

Независимо от того, создаете ли вы проект в Unreal Editor for Fortnite (UEFN) или проектируете выделенный сервер в Unreal Engine 5, понимание причин сбоя replication при аттачах критически важно. В этом туториале мы разберем механику Network Dormancy, почему аттачи ломают client-side prediction и как заставить replication graph уважать состояние вашего мира.

Почему аттачи ломают Network Updates

Чтобы исправить десинхрон, нужно понять, как Unreal Engine иерархически обрабатывает actor replication.

Когда character actor прикрепляется к пропу, его transform становится относительным (relative) по отношению к родителю. Для экономии трафика Unreal Engine агрессивно использует концепцию Network Dormancy.

Когда игрок сидит и не совершает активных движений, сервер может пометить актера игрока как dormant (спящий). Сервер считает: «Игрок не движется самостоятельно, значит, мне не нужно слать обновления для него. Я буду слать обновления только для движущегося кресла».

Математика десинхрона

  • Server Tick Rate: Обычно 30Гц в UEFN.
  • Prop NetUpdateFrequency: Часто по умолчанию 100 обновлений в секунду.
  • Character MinNetUpdateFrequency: Может падать до 2.0 при отсутствии инпута.

При вызове MoveTo кресло обновляется на 30Гц. Но так как игрок находится в состоянии dormancy, другие клиенты не получают RPC (Remote Procedure Call), сообщающий об обновлении относительной позиции игрока. Итог — жесткий визуальный десинхрон.

Шаг 1: Решение в UEFN Verse

Разработчики заметили: если встать с кресла, проблема исчезает. Это происходит потому, что смена movement mode с Custom на Walking заставляет сервер сбросить (flush) Network Dormancy.

Мы можем программно воссоздать этот «сброс» в Verse через микро-телепортацию, чтобы «разбудить» replication graph.

# [Код Verse без изменений]

Вызывая TeleportTo в те же координаты, мы заставляем движок C++ выставить флаг TeleportPhysics, что полностью сбрасывает client-side prediction для этого актера.

Шаг 2: Нативный фикс в Unreal Engine C++

Если у вас есть доступ к исходному коду, вы можете напрямую управлять dormancy через networking API.

// Пример на C++
// [Код C++ без изменений]

Шаг 3: Сохранение состояния в Backend

Исправление десинхрона в реальном времени — это только половина дела. Если в вашей игре есть персистентный мир, важно сохранять в базу данных корректные server-authoritative координаты. Создание своего бэкенда для частых сохранений занимает недели. horizOn предлагает Backend-as-a-Service, созданный специально для разработчиков игр.

5 советов по Multiplayer Movement

  1. Никогда не верьте состоянию аттача на клиенте: Используйте server-authoritative RPC.
  2. Управляйте NetDormancy вручную: Вызывайте FlushNetDormancy при активном движении.
  3. Избегайте глубоких иерархий: Не делайте аттачи более чем в один уровень.
  4. Используйте надежные RPC для важных изменений: NetMulticast для посадки/высадки.
  5. Проверяйте Transform при высадке: Сверяйте позицию на сервере при выходе из транспорта.

Заключение

Мультиплеерные десинхроны — это результат агрессивной оптимизации трафика. Понимая Network Dormancy, вы можете принудительно обновлять состояние через Verse или C++. Возьмите replication graph под свой контроль.

Нужен масштабируемый бэкенд? Попробуйте horizOn бесплатно.