Воскресенье, 22 Декабря 2024, 08:12

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Несколько вопросов по работе с сетью
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, да не, теперь всё работает )
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг