Войти
UnityФорумСеть

Unity3D: подскажите что за "NetworkReader:ReadByte out of range"?

#0
12:25, 16 мая 2016

Привет всем!
Работаю с сетью, наткнулся на такую ошибку:

IndexOutOfRangeException: NetworkReader:ReadByte out of range:NetBuf sz:64 pos:64
UnityEngine.Networking.NetBuffer.ReadByte () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkBuffer.cs:35)
UnityEngine.Networking.NetworkReader.ReadByte () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:161)
UnityEngine.Networking.NetworkReader.ReadPackedUInt32 () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:61)
UnityStandardAssets.Network.LobbyManager+MsgTypes+PlayerPrefabMsg.Deserialize (UnityEngine.Networking.NetworkReader reader)
UnityEngine.Networking.NetworkMessage.ReadMessage[PlayerPrefabMsg] () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/UNetwork.cs:161)
UnityStandardAssets.Network.LobbyManager.OnRequestPrefab (UnityEngine.Networking.NetworkMessage netMsg) (at Assets/Standard Assets/Network/Scripts/Lobby/LobbyManager.cs:464)
UnityStandardAssets.Network.LobbyManager.UpdateDrone () (at Assets/Standard Assets/Network/Scripts/Lobby/LobbyManager.cs:458)
UnityStandardAssets.Network.LobbyPlayer.UpdateDrone () (at Assets/Standard Assets/Network/Scripts/Lobby/LobbyPlayer.cs:332)
UnityEngine.Events.InvokableCall.Invoke (System.Object[] args)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters)
UnityEngine.Events.UnityEvent.Invoke ()
UnityEngine.UI.Button.Press () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1

Вроде как тут беда с PlayerPrefabMsg.Deserialize, но как узнать где? Не понимаю причину ошибки, думаю что тут что-то с сереализацией не то, может MessageType какой-то конфликт... проверил, идентификатры каждого типа сообщений уникальны.


#1
12:30, 16 мая 2016

вроде как тут говорится что был выход за диапазон буфера  равного 64, оттого и ошибка

#2
12:31, 16 мая 2016

Alerr
> IndexOutOfRangeException
Пыташся прочитать больше чем пришло.

#3
12:32, 16 мая 2016

Dikoobraz
Опередил :)

#4
12:49, 16 мая 2016

Есть подозрение на то что я криво сделал одну вещь:
игроки должны выбрать себе персонажа для игры. Если персонаж выбирается до входа в лобби, то работает вот такая штука:

public class MsgTypes {
      public const short PlayerPrefab = MsgType.Highest + 4;

      public class PlayerPrefabMsg : MessageBase {
        public short controllerID;    
        public short prefabIndex;
      }
    }
    
    public short playerPrefabIndex;// Это индекс персонажа (префаб зареган в Spawnable)

    public override void OnStartServer() {// serv
      NetworkServer.RegisterHandler(MsgTypes.PlayerPrefab, OnResponsePrefab);
      base.OnStartServer();
    }
      
    // OnClientConnect вызывает это base.OnClientConnect(conn); и это:
    public void OnClientConnect2(NetworkConnection conn) {// cl
      // base.OnClientConnect(conn); was called
      client.RegisterHandler(MsgTypes.PlayerPrefab, OnRequestPrefab);
    }

    // Called on the server when a client adds a new player with ClientScene.AddPlayer. // OnClientEnterLobby->ClientScene.AddPlayer
    public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId){// serv
      MsgTypes.PlayerPrefabMsg msg = new MsgTypes.PlayerPrefabMsg();
      msg.controllerID = playerControllerId;
      msg.prefabIndex = playerPrefabIndex;
      NetworkServer.SendToClient(conn.connectionId, MsgTypes.PlayerPrefab, msg);
    }

    // Вызывается по нажатию кнопки в лобби
    NetworkMessage NETMSG;
    public void UpdateDrone(){
      SetBigHero ();
      OnRequestPrefab (NETMSG);
    }
    // server <- client
    private void OnRequestPrefab(NetworkMessage netMsg) {// cl
      NETMSG = netMsg;
      MsgTypes.PlayerPrefabMsg msg = new MsgTypes.PlayerPrefabMsg();
      msg.controllerID = netMsg.ReadMessage<MsgTypes.PlayerPrefabMsg>().controllerID;
      msg.prefabIndex = playerPrefabIndex;
      client.Send(MsgTypes.PlayerPrefab, msg);
    }
    // client <- server
    private void OnResponsePrefab(NetworkMessage netMsg) {// serv
      MsgTypes.PlayerPrefabMsg msg = netMsg.ReadMessage<MsgTypes.PlayerPrefabMsg>();  

      //playerPrefab = spawnPrefabs[msg.prefabIndex];
      //gamePlayerPrefab = spawnPrefabs[msg.prefabIndex];
      OnLobbyServerCreateLobbyPlayer22(netMsg.conn, msg.prefabIndex);

      base.OnServerAddPlayer(netMsg.conn, msg.controllerID);
      //Debug.Log(playerPrefab.name + " spawned!");
    }

    Dictionary<int, int> currentPlayers = new Dictionary<int, int> ();// serv
    public void OnLobbyServerCreateLobbyPlayer22(NetworkConnection conn, short playerControllerId) {
      if (!currentPlayers.ContainsKey (conn.connectionId))
        currentPlayers.Add (conn.connectionId, playerControllerId);// 0
      else {
        currentPlayers.Remove(conn.connectionId);
        currentPlayers.Add (conn.connectionId, playerControllerId);
      }
    }
      
    public override GameObject OnLobbyServerCreateGamePlayer(NetworkConnection conn, short playerControllerId) {// serv
      int index = currentPlayers[conn.connectionId];

      GameObject _temp = (GameObject)GameObject.Instantiate(spawnPrefabs[index],
        Vector3.zero,//startPositions[0].position conn.connectionId
        Quaternion.identity);
      NetworkServer.AddPlayerForConnection(conn, _temp, playerControllerId);//

      return _temp;
    }
    // Вызыается извне для установки индекса префаба при до перехода в лобби
    public void SetBigHero () {
      playerPrefabIndex = (short)((int)playerPrefabIndex == 0 ?  1 : 0);
    }

Если выставить флажок префаба до перехода в лобби (public void SetBigHero ()), а затем перейти в него, то префаб меняется...
Если мы в лобби хотим менять персонажа, то вызываем вот это: public void UpdateDrone(); Но для вызова нужно иметь вот это: NetworkMessage NETMSG;
Его сохраняем при переходе в лобби вот тут: private void OnRequestPrefab(... 
Так вот, есть подозрение, что сохранять NETMSG в методе OnRequestPrefab нельзя, верно? NetworkMessage, который передатся в OnRequestPrefab меняется?
Как получить NetworkMessage чтобы отправлять сообщения? Или у меня неверный принцип смены персонажа?

#5
13:30, 16 мая 2016

Структура обширная, сразу неясно где косяк, debug.log в помощь(бывает что результат приходит из другого места откуда и не ждешь) плохо конечно breakpoint'ов не поставить при работе с юнити

#6
13:42, 16 мая 2016

Брек поинты можно ставить. Пока переписал код, избавился от:  NETMSG = netMsg;
Похоже что так делать нельзя.
Я не совсем понимаю вот эти строки:

netMsg.ReadMessage<MsgTypes.PlayerPrefabMsg>().controllerID;
и
client.connection.connectionId;
Вот это в тупик ставит: netMsg.ReadMessage, что это?
controllerID это client.connection.connectionId ?

#7
14:10, 16 мая 2016

Dikoobraz
> плохо конечно breakpoint'ов не поставить при работе с юнити

Лолшто? Ты такое откуда взял?
Такое было как минимум уже в Юнити 3.х.
А сейчас так и подавно всё работает.

#8
14:16, 16 мая 2016

Ставлю брек поинты, можно ставить в MonoDev, можно в VisualStudio... Вот пример брек-поинта:

+ Показать

#9
15:06, 16 мая 2016

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

#10
16:18, 16 мая 2016

Повторю вопрос:
>Я не совсем понимаю вот эти строки:
>netMsg.ReadMessage<MsgTypes.PlayerPrefabMsg>().controllerID;

>client.connection.connectionId;
>Вот это в тупик ставит: netMsg.ReadMessage, что это?
>controllerID это client.connection.connectionId ?

UnityФорумСеть

Тема в архиве.