Как я могу синхронизировать двух игроков?

8

Я работаю над мобильной игрой Unity, очень похожей на многопользовательскую версию Temple Run . Я наблюдаю колебания сетевой задержки (обычно 200-500 мс) из-за мобильной платформы.

Два персонажа игрока показаны бегущими по одному и тому же пути и должны выполнять простые действия (прыжок, скольжение, усиление и т. Д.), Чтобы пройти препятствия.

Когда сообщение приходит с опозданием, игра предполагает, что удаленный игрок преодолел препятствие. Обычно это работает хорошо, но в случае, если игрок убит препятствием, я хочу, чтобы удаленный игрок погиб на том же препятствии / позиции, что и местный игрок. Из-за задержек удаленный игрок, по-видимому, пересек препятствие еще до того, как пришло сообщение о его смерти.

Как я могу синхронизировать игроков?


Я попытался переместить удаленного игрока обратно в положение смерти локального игрока сразу же, как только пришло сообщение о смерти, визуально это выглядит неловко и может вызвать другие проблемы с синхронизацией.

Зохайб Джавед
источник

Ответы:

10

Анализ проблем

Связь в реальном времени через соединение с высокой задержкой, очевидно, невозможна.

Конечно, вы можете попытаться создать иллюзию (как вы делаете, заставляя удаленного игрока, кажется, преодолеть препятствие, когда это еще не известно). Когда эта иллюзия не проходит (как у вас, когда удаленный игрок фактически не преодолел препятствие, но умер вместо этого ), больше ничего нельзя сделать.

проблема

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

Потенциальное решение

Как насчет буквального замедления другого игрока, если его решение требует времени для распространения?

решение

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

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

Анко
источник
Спасибо за ответ. Мы уже опробовали потенциальное решение, которое вы предложили, но не нашли его возможным по следующим причинам: 1. Первая причина - высокая скорость моей игры. Чтобы закрыть окно 200 мс, мне пришлось бы замедлить удаленного игрока до 1/4 скорости, что вызывает очень неприятную и видимую визуальную аномалию, особенно в случае, когда игрок бежит рядом. 2. Поскольку задержка колеблется, действительно трудно рассчитать снижение скорости для удаленного игрока, которое гарантировало бы, что сообщение прибудет до того, как оно пересечет препятствие.
Зохайб Джавед
2
@ZahaibJaved Часто единственное реальное решение - скрыть задержку с помощью анимации. Вместо того, чтобы замедляться, когда они приближаются к препятствию, подумайте о том, чтобы полностью остановиться на краю и выполнить анимацию «готовясь к прыжку», на воспроизведение которой уходит целая секунда. Как только пакет "они сделали это" проходит, выполните фактический прыжок и прыгайте вперед к своей реальной позиции.
BlueRaja - Дэнни Пфлюгофт
Извините за задержку с ответом. Таким образом, решение, которое я реализовал, состояло в запуске кат-сцены, где можно увидеть всех игроков. Местный игрок всегда на первой позиции. После окончания ролика. Я просто отодвигаю всех удаленных игроков назад на достаточное количество, чтобы они могли некоторое время получать информацию о том, что местный игрок погиб на конкретном препятствии или скользить или прыгать правильно на пути. И, в конце концов, есть прямой путь, по которому я снова синхронизирую игроков. Так что этот результат отображается правильно.
Зохайб Джавед
4

Чтобы дополнить ответ Анко, вы можете немного изменить свой игровой дизайн, добавив последствия неудачного препятствия после неудачи, например, неудачный прыжок приводит к приземлению в лужу грязи, которая дисквалифицирует игрока. Таким образом, другой игрок замечает неудачу, видя другое падение в грязи, в то время как проигравший игрок сразу же видит это.

Вот хороший пост в блоге об этой проблеме (это не так уж недавно, но довольно интересно): Управление временем и синхронизация Даррина Уэста .

Vaillancourt
источник
1

Для местного игрока так важно знать точную позицию смерти удаленного игрока? Допустим, удаленный игрок не смог перепрыгнуть через одно из ваших препятствий и поэтому умер.

Мертвый игрок сразу же увидит их смерть и продолжит путь с места происшествия. Здесь нет ничего волшебного.

Местный игрок (тот, кто еще жив и пинается) видел, как удаленный игрок успешно преодолевает препятствие. Появится уведомление о смерти. Удаленный игрок может споткнуться, упасть и медленно исчезнуть. В следующий раз, когда вы узнаете позицию удаленного игрока, игрок перейдет в эту точную позицию и снова начнет нормально работать. В такой ситуации игроки будут знать о задержке, но задержка будет представлена ​​как игровой элемент (спотыкаясь), а не внезапно появляющиеся и исчезающие игроки.

Если скорость обоих игроков постоянна, траектория движения предопределена, и время, необходимое для восстановления после падения, известно, что вы можете полностью устранить исчезающую / исчезающую часть. Вообразите удаленного игрока, умирающего в одном из препятствий. Его локальное представление все еще работает, когда приходит уведомление. Игрок сразу же спотыкается. Им нужно время, чтобы встать и снова начать бежать. На самом деле, это занимает столько же времени, как если бы им показывали, что они умирали на препятствии. Таким образом, когда они снова работают и работают, как локальные, так и удаленные позиции синхронизируются.


источник