Физика не синхронизируется правильно по сети при использовании Bullet

11

Я пытаюсь реализовать физическую систему клиент / сервер, используя Bullet, но у меня возникают проблемы с синхронизацией.

Я реализовал собственное состояние движения, которое считывает и записывает преобразование из моих игровых объектов, и оно работает локально, но я пробовал два разных подхода для сетевых игр:

  1. Динамические объекты на клиенте, которые также находятся на сервере (например, не случайный мусор и другие неважные вещи), становятся кинематическими. Это работает правильно, но объекты движутся не очень плавно
  2. Объекты являются динамическими на обоих, но после каждого сообщения от сервера о том, что объект перемещен, я устанавливаю линейную и угловую скорость на значения с сервера и вызываю btRigidBody :: continueToTransform с преобразованием на сервере. Я также вызываю btCollisionObject :: activ (true); заставить объект обновить.

Мое намерение с методом 2 было в основном сделать метод 1, но угоня Bullet, чтобы сделать прогноз бедного человека вместо того, чтобы делать мой собственный, чтобы сгладить метод 1, но это, похоже, не работает (по причинам, которые не ясны на 100% я даже перешагнул пулю) и предметы иногда оказываются в разных местах.

Я иду в правильном направлении? Кажется, в Bullet встроен собственный код интерполяции. Может ли это помочь мне сделать метод 1 лучше? Или мой код метода 2 не работает, потому что я случайно топаю это?

РЕДАКТИРОВАТЬ: Другая проблема с методом 1, который я только что заметил, заключается в том, что реакция на столкновение будет далека для столкновений с несинхронизированными объектами. Кинетические тела иногда стреляют в бесконечность, так как их нельзя отбросить назад.

Лукас
источник
Несколько вещей, которые могут помочь вам получить ответ: Какой язык / движок вы используете? Какой тип соединения это? Насколько плох дефицит синхронизации по сравнению с пингом на сервере?
Fibericon
2
Второй вариант не работает, потому что вы устанавливаете скорости на значения сервера только после нескольких кадров, поэтому между каждым пакетом есть несколько кадров, где все может дрейфовать. Я бы порекомендовал прочитать все посты Гаффера по игровой физике. Возможно, вам следует сначала прочитать «исправьте ваш временной шаг», но вот последняя статья, в которой говорится о сетевой физике gafferongames.com/game-physics/networked-physics
Рой Т.
Я использую самостоятельно разработанный движок в C ++. Однако я почти уверен, что дефицит синхронизации не так уж и плох, вероятно, 1 кадр за пингом, если я должен был догадаться, но я все еще в основном тестирую только локальную сеть. Я проверю эти статьи, и, да, вы правы, что скорости отключены. Однако вещи далеко , как ящик по всей карте. Разве явная настройка преобразования не должна в конечном итоге привести вещь в соответствие? (даже если это еще не красиво, покачивание и т. д.)
Лукас
Я прочитал пост Гаффера, и он был информативным, но, похоже, он касался в основном движений игроков, над которыми я уже работал. Я читал вокруг, и кажется, что мой код метода 2 практически идентичен методу, используемому в движке Unreal . Они не предоставляют много деталей, но это заставляет меня задаться вопросом, является ли идея обоснованной, но мое использование Bullet просто неправильно.
Лукас
Интересное чтение, которое частично связано с вашей темой: gamasutra.com/view/feature/3094/… . Речь идет о RTS, а не о физике, но они достигают точки, где они должны синхронизировать симуляцию на сервере и клиентах. Как они это делают? Они запускают независимые симуляции как на клиенте, так и на сервере, но сервер отправляет пакеты посылок, которые удостоверяются, что симуляция клиента не расходится и корректируется, если это произойдет ...
Том ван Грин

Ответы:

4

Вам нужно правильное предсказание на стороне клиента .

Вы должны действительно подробно прочитать ссылку, которую Рой Т. предоставил вам в своем комментарии . Он описывает, что делать с вводом игрока и физикой персонажей, но принцип остается тем же для «физики, управляемой сервером».

Это не просто реализовать, но в двух словах, для игровых объектов, которые должны быть синхронизированы:

  • Запустите физику как на сервере, так и на клиенте;
  • Сервер регулярно отправляет обновления;
  • Клиент непрерывно и плавно перестраивает свой физический мир под значения сервера.

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

Что касается вашей настоящей ошибки, я не знаком с Bullet, но вы, вероятно, пропускаете некоторые значения, например, вы установили линейную и угловую скорости, но вы установили ускорения?

Лоран Кувиду
источник
Спасибо! Это заставляет меня чувствовать себя лучше, потому что я на правильном пути. Я сейчас проверю свой код с зубной расческой. Возможно, какое-то уведомление не запускается или, как вы говорите, я пропускаю значение, так как метод 2 должен (вяло) работать.
Лукас
3

Что я делаю лично, так это тот, кто ведет игру, создает мир физики и синхронизирует объекты с клиентами. Даже если это сетевая схема p2p, я по-прежнему использую физический движок на одном из клиентов проигрывателя.

Другая физика, которую я использую, это просто глаз, даже не нужно синхронизировать.

В прототипе, который я сделал некоторое время назад под названием «boatzerker», я запустил физику на хосте, и эффекты частиц (также используя физику) не были синхронизированы по сети, но независимы для каждого клиента, потому что они были приятными на вид.

tsturzl
источник
Спасибо, да, это один из способов. Тем не менее, это не приводит к хорошим ответам о столкновениях на клиенте с вещами, которые делает клиент, а также с приятными взглядами не всегда будут взаимодействовать правильно, поскольку они не могут оттолкнуть серверные вещи (по крайней мере, в течение этого временного шага). Я чувствую, что это должно быть возможно, так как движки вроде Unreal и Source, кажется, делают это.
Лукас
Eye Candy не нужно синхронизировать, его можно рассчитать для каждого клиента. ответ на клиенте рассчитывается на сервере, координаты для клиента просто рассчитываются и отправляются обратно, вы не отправляете обратный вызов клиенту, говоря, что он столкнулся, что, вероятно, будет выглядеть ужасно.
tsturzl
2

Невозможно реализовать сетевые синхронные физические миры. Небольшая разница в шаге N, конечно, гораздо большая разница в шаге N + 1. Вы не можете прикладывать силы или импульсы, чтобы поддерживать их синхронизацию и выглядеть реалистично.

Решения: -

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

  2. Вы можете иметь один физический мир на сервере и транслировать позиции и скорости объектов для клиентов.

Максимум
источник
Вы можете попробовать сыграть в сетевую игру с физикой, чтобы увидеть, что миры не синхронизированы. Например, Need For Speed ​​World бесплатен, имеет многопользовательскую игру и базовую физику. (коробки на дороге и разрушаемые предметы)
Макс
Я не уверен, что точно следую за тобой. Я уверен, что это возможно, так как многие игры позволяют игрокам бросать ящики (например). Кажется, что ваш вариант 2 похож на мой вариант 2, но я не могу заставить Bullet точно привязать объекты к их серверным позициям. Может быть, это моя корневая проблема?
Лукас
1
Нет. Обычно это иллюзия синхронности. Если вы сравните экраны, то увидите, что когда вы подпрыгиваете в ящиках, ящики летят в разных направлениях. или коробки вообще не являются физикой (просто анимация). Количество ящиков разное. Когда я говорю анимацию, я имею в виду, что за движениями нет никакой физической анимации. Они не делают различных уловок, чтобы картина выглядела несколько синхронно, но это не синхронные физические миры. Вы должны посмотреть и сравнить, как они движутся в разных играх.
Макс