Несколько вопросов по работе с сетью
| |
White9 | Дата: Среда, 24 Сентября 2014, 18:06 | Сообщение # 1 |
заслуженный участник
Сейчас нет на сайте
| Всем привет ) Очень мало работал со стандартной сетью на Unity, а недавно появилась в ней необходимость, в связи с чем возникли несколько вопросов 1) Как полностью удалять объекты со сцены? То есть чтобы игрок, подключившийся после удаления данного объекта, его не видел. Сейчас же получается, что если кто-то, к примеру, убил противника, то все это видят, но стоит отключится от сервера и перезайти, как противник снова на месте (отображается локально только у того, кто перезаходил) 2) Как передавать текстовые переменные по сети? stream.Serialize с ними не работает. 3) Кстати вопросы по нему. Предположим у меня есть куб, при нажатии на который он по скрипту передвигается. Ставлю ему компонент NetworkView и простенький скрипт с использованием stream.Serialize, который хорошо работает на персонажах. Но дело в том, что при нажатии куб двигается не у всех. Встречались следующие ситуации а) При нажатии сервером куб движется у всех игроков б) При нажатии клиентом куб движется только у него. Если перезойти, то берётся позиция куба по серверу В чём здесь может быть ошибка, если тот же код хорошо работает на персонажах? Всем заранее спасибо за ответы )
|
|
| |
GantZ_Yaka | Дата: Четверг, 25 Сентября 2014, 06:50 | Сообщение # 2 |
почетный гость
Сейчас нет на сайте
| Работал с TNet, отличия есть, но суть одна. 1)Нужно смотреть на каждого игрока - как на отдельную игру со своей загруженной сценой, которые должны синхронизироваться между собой. Если взять простой пример с комнатами, где сервер один, а игровых комнат много. В каждой такой комнате один из игроков является хостом, т.е. самой важной фигурой, его игровая сцена и все события на ней должны быть образцом того, что реально происходит в игре. Когда новый игрок присоединяется к групповой игре (или переподключается после потери связи), прежде всего хост должен отправить ему все данные о том, что происходит сейчас в игровой сцене - это может быть отправка пакета с кучей данных - кто где стоит, лежит, кто ранен, у кого что в руках, где аптечки есть, где их нет и т.д. Игрок должен этот пакет переварить и обновить объекты в своей сцене. 2) можно отправлять переменную текста в RPC http://docs.unity3d.com/ru/current/Manual/class-NetworkView.html 3) хз, нужно проект смотреть, но похоже на то, что у тебя сервер - хозяин куба и стоит проверка: если куб - мой, то отправляй всем данные о его премещениях.
|
|
| |
White9 | Дата: Четверг, 25 Сентября 2014, 11:57 | Сообщение # 3 |
заслуженный участник
Сейчас нет на сайте
| GantZ_Yaka, спасибо ) 1) Это я понимаю ) Просто непонятно как именно отслеживать что объект был удалён. Или стоит всё записывать с помощью индексов в отдельный скрипт и там проверять состояние каждого объекта? Пришла в голову идея перед удалением опускать объект на отрицательную высоту, а там уже в отдельном скрипте ставить условие на эту высоту и делать удаление. Таким образом у вновь зашедшего игрока позиция куба будет отрицательной (так как, по логике, это последняя позиция перед удалением) и он тут же удалится. Правда, это я пока не пробовал ) 2) Я читал, но так до конца и не понял. Как делал я - в отдельной функции, вызываемой RPC, присваивал тексту над персонажем ту локальную переменную, которую тот вводил в необходимое поле. Работало это только локально, то есть другие игроки ника не видели. Появилась идея с помощью RPC и интанса в этой же функции создавать плашку и тут же присваивать ей текст (где то видел подобное решение) 3) Кажется я понимаю о чём ты ) То есть он записывает и передаёт только ту позицию, которая в данный момент у сервера? А можно ли как-то это исправить? Вот код, который в моём скрипте отвечал за это Код void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info) { Vector3 syncPosition = Vector3.zero; // обязательно должен быть инициализирован перед приемом Quaternion syncRotation = Quaternion.identity; if (stream.isWriting) { syncPosition = transform.position; // считываем текущую позицию stream.Serialize(ref syncPosition); // синхронизируем с сетью
syncRotation = transform.rotation; // считываем текущий поворот stream.Serialize(ref syncRotation); // синхронизируем с сетью } else { stream.Serialize(ref syncPosition); // получаем позицию из сети transform.position = syncPosition; // записываем позицию в наш объект.
stream.Serialize(ref syncRotation); // получаем поворот из сети transform.rotation = syncRotation; // записываем поворот в наш объект } }
Сообщение отредактировал White9 - Четверг, 25 Сентября 2014, 11:59 |
|
| |
allods | Дата: Четверг, 25 Сентября 2014, 12:39 | Сообщение # 4 |
почти ветеран
Сейчас нет на сайте
| должна быть такая функция как
Network.Destroy(); или что то типа того, при удалении таким образом у уже зашедших игроков этот объект не будет спавнится , но проблема в том что этот объект должен спавнится в начале игры а не уже существовать. Если тебе нужно удалять игроков то это то что тебе нужно, ибо игроки спавнятся .
Добавлено (25.09.2014, 12:39) --------------------------------------------- Вот это вам нужно я думаю
Network.Destroy()
пруф
Сообщение отредактировал allods - Четверг, 25 Сентября 2014, 12:40 |
|
| |
White9 | Дата: Четверг, 25 Сентября 2014, 13:10 | Сообщение # 5 |
заслуженный участник
Сейчас нет на сайте
| allods, спасибо, использовал эту функцию, но не знал, что она не действует на те объекты, которые изначально на сцене ) Дописал код, теперь отображение имён работает. Скажите, правильно ли я понимаю, что когда нам нужно переслать остальным изменения в переменных, то всегда нужно использовать вот эту строчку? Код networkView.RPC("Name", RPCMode.AllBuffered, viewID, Nick); , где Name - название метода, Nick - изменённый параметр, viewID - переменная, необходимая для присвоения ID новому объекту Код public void Awake() { if (!networkView.isMine) { Destroy(Camera1); enabled = false; } else { gameObject.tag = "MyPlayer"; Connect1 = GameObject.Find("Connect"); Nick = Connect1.GetComponent<Connect>().connectNickname; NetworkViewID viewID = Network.AllocateViewID(); networkView.RPC("Name", RPCMode.AllBuffered, viewID, Nick); } } [RPC] public void Name (NetworkViewID viewID, string location) { GameObject N = (GameObject)Network.Instantiate(NickName, transform.position, transform.rotation, 0); N.transform.parent = transform; NetworkView nView; nView = N.GetComponent<NetworkView>(); nView.viewID = viewID; N.transform.localPosition = new Vector3(0, 1.2f, 0); N.GetComponent<TextMesh>().text = location; }
Сообщение отредактировал White9 - Четверг, 25 Сентября 2014, 14:24 |
|
| |
allods | Дата: Четверг, 25 Сентября 2014, 14:21 | Сообщение # 6 |
почти ветеран
Сейчас нет на сайте
| Может плашку уже в сам префаб засунуть, или самим префабом instantiate и двигать через код. И в эту плашку отсылать имя игрока
|
|
| |
White9 | Дата: Четверг, 25 Сентября 2014, 14:54 | Сообщение # 7 |
заслуженный участник
Сейчас нет на сайте
| allods, да не, теперь всё работает )
|
|
| |
|