Сетевой арканоид на двоих.

Сеть в Unity3D

Сетевой арканоид на двоих.

Сообщение stash 19 янв 2011, 17:44

Это должен был быть просто учебный проект - игра-арканоид, но как-то она разрослась и уже несколько раз переделывалась и все такое.

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

Основная трудность в том, что для арканоида критично время отклика. То есть игрок должен сразу видеть последствия своих действий. Соответственно, сетевая архитектура - неавторитетная. Каждый клиент отвечает за свою пластину. И игрок сразу видит отклик на управление. Соответственно, другой игрок (игра на 2) видит то, что произошло с пластиной первого игрока через время равное one-way latency.

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

Что пришло мне в голову - разбить игровое поле на две части. Левая часть поля принадлежит клиенту, правая - серверу. Между ними граница, назовем ее трешхолд. Соответственно в левой части поля физика считается на клиенте, а в правой - на сервере. Это работает. Но. В методе OnSerializeNetworkView только владелец объекта может передавать данные, все остальные могут только получать. Соответственно, каждый раз при переходе через трешхолд приходиться изменять владельца мяча. Но в юнити это невозможно. NetworkView.owner is readonly. Я не могу изменить владельца. Поэтому я каждый раз делаю Network.Destroy на одной стороне трешхолда, уничтожая объект, а потом на другой стороне делаю Network.Instantiate, воссоздавая мяч. И опять же все это работает, но при прохождении трешхолда мяч дергается.

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

И я хочу каким-то образом на небольшом участке свести эти два объекта воедино. То есть мне вероятно нужна какая-то корутина чтобы постепенно замедлять рендерер мяча, пока он не встретится с мячом.

Хм, написал все это и в общем-то понял что и как делать. Правильно заданный вопрос - большая часть ответа. Ладно тогда более общий вопрос: может все это идиотизм - и есть какое-то легкое и очевидно решение для все проблемы, которое я не увидел?

Вот что есть на текущий момент: http://allunity3d.com/scene/234/
Чтобы сыграть по сети, IP сервера придется вбить руками. IP сервера должен быть реальным.
stash
UNец
 
Сообщения: 5
Зарегистрирован: 26 дек 2010, 22:47

Вернуться в Сеть

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3