Search Unity

Third Party Mirror: Serialization error and syncvar hook not called

Discussion in 'Multiplayer' started by axschacher, Oct 19, 2021.

  1. axschacher

    axschacher

    Joined:
    Mar 14, 2018
    Posts:
    21
    Hello,

    Currently I am trying to set display names when players connect. It works on the host client, however I get this error on a joining client. The joining client does seem to update the display name syncVar, however the handler hook is not called. I'm not sure if these are related or not. If I comment out the SetDisplayName calls in the NetworkManager, I don't get the Serialization error.


    Custom NetworkManager OnServerAddPlayer

    Code (CSharp):
    1.  override public void OnServerAddPlayer(NetworkConnection conn)
    2.     {
    3.         base.OnServerAddPlayer(conn);
    4.  
    5.         GameObject playerObj = Instantiate(playerCharacterPrefab, new Vector3(3f, 0.5f, 3f), Quaternion.identity);
    6.         NetworkServer.Spawn(playerObj, conn);
    7.  
    8.         NetPlayer netPlayer = conn.identity.GetComponent<NetPlayer>();
    9.         netPlayer.SetControlledEntityNetId(playerObj.GetComponent<NetworkIdentity>());
    10.         listOfConnectedPlayers.Add(netPlayer);
    11.  
    12.         if (isSteamNetManager)
    13.         {
    14.             CSteamID steamId = SteamMatchmaking.GetLobbyMemberByIndex(SteamLobby.LobbyID, numPlayers - 1);
    15.             netPlayer.SetDisplayName(SteamFriends.GetFriendPersonaName(steamId));
    16.         }
    17.         else
    18.         {
    19.             netPlayer.SetDisplayName("Player " + numPlayers);
    20.         }
    21.     }
    NetPlayer class (Set as the Auto Created Player Prefab in Network Manager)
    Code (CSharp):
    1. public class NetPlayer : NetworkBehaviour
    2. {
    3.     #region Display Name
    4.  
    5.     [SyncVar(hook = nameof(UpdateDisplayName))] private string displayName = "missingNo";
    6.  
    7.     [Server] public void SetDisplayName(string newDisplayName) => displayName = newDisplayName;
    8.  
    9.     public string GetDisplayName() => displayName;
    10.  
    11.     private void UpdateDisplayName(string oldDisplayName, string newDisplayName)
    12.     {
    13.         GameObject playerObj = NetworkIdentity.spawned[controlledEntityNetId.netId].gameObject;
    14.         UiFollowObject ui = playerObj.GetComponent<UiFollowObject>();
    15.         if (ui != null)
    16.         {
    17.             ui.SetText(newDisplayName);
    18.         }
    19.     }
    20.     #endregion
    21.  
    22.     [SyncVar] private NetworkIdentity controlledEntityNetId;
    23.     [Server] public void SetControlledEntityNetId(NetworkIdentity netId) => controlledEntityNetId = netId;
    24. }
    Console Error Log:
    Code (CSharp):
    1. OnDeserialize was expected to read 11 instead of 10 bytes for object:NetPlayer(Clone) component=NetPlayer sceneId=0. Make sure that OnSerialize and OnDeserialize write/read the same amount of data in all cases.
    2. UnityEngine.Logger:Log(LogType, Object)
    3. Mirror.ILoggerExtensions:LogWarning(ILogger, Object) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/Logging/LogFactory.cs:93)
    4. Mirror.NetworkIdentity:OnDeserializeSafely(NetworkBehaviour, NetworkReader, Boolean) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/NetworkIdentity.cs:1043)
    5. Mirror.NetworkIdentity:OnDeserializeAllSafely(NetworkReader, Boolean) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/NetworkIdentity.cs:1061)
    6. Mirror.ClientScene:ApplySpawnPayload(NetworkIdentity, SpawnMessage) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/ClientScene.cs:760)
    7. Mirror.ClientScene:OnSpawn(SpawnMessage) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/ClientScene.cs:781)
    8. Mirror.<>c__DisplayClass31_0`1:<RegisterHandler>b__0(NetworkConnection, SpawnMessage) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/NetworkClient.cs:328)
    9. Mirror.<>c__DisplayClass6_0`2:<MessageHandler>b__0(NetworkConnection, NetworkReader, Int32) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/MessagePacker.cs:128)
    10. Mirror.NetworkConnection:InvokeHandler(Int32, NetworkReader, Int32) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/NetworkConnection.cs:191)
    11. Mirror.NetworkConnection:TransportReceive(ArraySegment`1, Int32) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/NetworkConnection.cs:249)
    12. Mirror.NetworkClient:OnDataReceived(ArraySegment`1, Int32) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/NetworkClient.cs:174)
    13. UnityEngine.Events.UnityEvent`2:Invoke(ArraySegment`1, Int32)
    14. kcp2k.KcpTransport:<Awake>b__11_1(ArraySegment`1) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs:45)
    15. kcp2k.KcpClient:<Connect>b__6_1(ArraySegment`1) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpClient.cs:46)
    16. kcp2k.KcpConnection:TickAuthenticated(UInt32) (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpConnection.cs:236)
    17. kcp2k.KcpConnection:Tick() (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpConnection.cs:256)
    18. kcp2k.KcpClient:Tick() (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpClient.cs:91)
    19. kcp2k.KcpTransport:LateUpdate() (at C:/Users/Alex/Documents/GitHub/sandbox-game/Assets/Plugins/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs:93)
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    It looks like the base OnServerAddPlayer you're calling instantiates the player prefab, and you are also instantiating one in the override. Also I think you need to AddPlayerForConnection after instantiating the player.
     
  3. axschacher

    axschacher

    Joined:
    Mar 14, 2018
    Posts:
    21
    Yes sorry, I forgot to mention that there are two objects being instantiated for each player, which may seem redundant, but I am trying to keep an object that represents the player on that connection separate from their in-game character, which could be destroyed or swapped out. So a GameObject called NetPlayer with the NetPlayer script on it is the default player object for the NetManager to spawn on its own when a player connects. Then, I manually spawn a player character object for that player to control in OnServerAddPlayer, and give that connection authority for that object, as well as keep a reference to that object in the NetPlayer. It all works well as far as authority and player control.

    The error i am getting seems irrelevant to this manually spawned character, I am only having issues with the NetPlayer gameobject and setting the display name to that object.
     
  4. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    I ran the code and got the same error. The error goes away if you remove the code from UpdateDisplayName so that's a good place to start looking for the problem.
     
  5. axschacher

    axschacher

    Joined:
    Mar 14, 2018
    Posts:
    21
    Right, not sure why I didn't continue to just keep trying each line. But its this line specifically causing the error:

    GameObject playerObj = NetworkIdentity.spawned[controlledEntityNetId.netId].gameObject;


    Must be something with how I am trying to retrieve a specific gameobject by its network identity. Going to look more into how to do that properly.

    Edit: Its because the net id (which i switched to just syncing the uint) is not getting set before the UpdateDisplayName runs. After reordering how variables are synced, it works now.
     
    Last edited: Oct 22, 2021