Error when trying to sync names across clients

I've been able to get every client to have the correct name, but only for their own client, so I'm trying to use this code to have player names be the same across all clients:

using Unity.Netcode;
using UnityEngine;

public class playerNetScript : NetworkBehaviour
{

    private readonly NetworkVariable<playerNetworkData> netState = new (writePerm: NetworkVariableWritePermission.Owner);

    void Update()
    {
        if (IsOwner) {
            netState.Value = new playerNetworkData() {
                Position = transform.position,
                Scale = transform.localScale,
                Name = transform.name
            };
        } else {
            transform.position = netState.Value.Position;
            transform.localScale = netState.Value.Scale;
            transform.name = netState.Value.Name;
        }
    }

    struct playerNetworkData : INetworkSerializable {
        private float x, y;
        private float xScale;
        private string playerName;

        internal Vector3 Position {
            get => new Vector3(x,y,0);
            set {
                x = value.x;
                y = value.y;
            }
        }

        internal Vector3 Scale {
            get => new Vector3(xScale,0.31f,1);
            set => xScale = value.x;
        }

        internal string Name {
            get => new string(playerName);
            set => playerName = Name;
        }

        public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
        {
            serializer.SerializeValue(ref x);
            serializer.SerializeValue(ref y);

            serializer.SerializeValue(ref xScale);

            serializer.SerializeValue(ref playerName);
        }
    }
}

It used to work fine before I added in code for player names, however after adding the code it started to give me this error after I tried connecting to a game I was hosting:

NullReferenceException: Object reference not set to an instance of an object
Unity.Netcode.FastBufferWriter.WriteValueSafe (System.String s, System.Boolean oneByteChars) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Serialization/FastBufferWriter.cs:534)
Unity.Netcode.BufferSerializerWriter.SerializeValue (System.String& s, System.Boolean oneByteChars) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Serialization/BufferSerializerWriter.cs:29)
Unity.Netcode.BufferSerializer`1[TReaderWriter].SerializeValue (System.String& s, System.Boolean oneByteChars) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Serialization/BufferSerializer.cs:67)
playerNetScript+playerNetworkData.NetworkSerialize[T] (Unity.Netcode.BufferSerializer`1[TReaderWriter] serializer) (at Assets/Scripts/playerNetScript.cs:54)
Unity.Netcode.UnmanagedNetworkSerializableSerializer`1[T].Write (Unity.Netcode.FastBufferWriter writer, T& value) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/NetworkVariable/NetworkVariableSerialization.cs:888)
Unity.Netcode.NetworkVariableSerialization`1[T].Write (Unity.Netcode.FastBufferWriter writer, T& value) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/NetworkVariable/NetworkVariableSerialization.cs:1595)
Unity.Netcode.NetworkVariable`1[T].WriteField (Unity.Netcode.FastBufferWriter writer) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/NetworkVariable/NetworkVariable.cs:233)
Unity.Netcode.NetworkBehaviour.WriteNetworkVariableData (Unity.Netcode.FastBufferWriter writer, System.UInt64 targetClientId) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkBehaviour.cs:987)
Unity.Netcode.NetworkObject.WriteNetworkVariableData (Unity.Netcode.FastBufferWriter writer, System.UInt64 targetClientId) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkObject.cs:1428)
Unity.Netcode.NetworkObject.SynchronizeNetworkBehaviours[T] (Unity.Netcode.BufferSerializer`1[T]& serializer, System.UInt64 targetClientId) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkObject.cs:1707)
Unity.Netcode.NetworkObject+SceneObject.Serialize (Unity.Netcode.FastBufferWriter writer) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkObject.cs:1641)
Unity.Netcode.SceneEventData.WriteSceneSynchronizationData (Unity.Netcode.FastBufferWriter writer) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/SceneManagement/SceneEventData.cs:531)
Unity.Netcode.SceneEventData.Serialize (Unity.Netcode.FastBufferWriter writer) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/SceneManagement/SceneEventData.cs:476)
Unity.Netcode.SceneEventMessage.Serialize (Unity.Netcode.FastBufferWriter writer, System.Int32 targetVersion) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Messaging/Messages/SceneEventMessage.cs:15)
Unity.Netcode.NetworkMessageManager.SendMessage[TMessageType,TClientIdListType] (TMessageType& message, Unity.Netcode.NetworkDelivery delivery, TClientIdListType& clientIds) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Messaging/NetworkMessageManager.cs:641)
Unity.Netcode.NetworkMessageManager.SendMessage[T] (T& message, Unity.Netcode.NetworkDelivery delivery, System.UInt64 clientId) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Messaging/NetworkMessageManager.cs:814)
Unity.Netcode.NetworkConnectionManager.SendMessage[T] (T& message, Unity.Netcode.NetworkDelivery delivery, System.UInt64 clientId) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Connection/NetworkConnectionManager.cs:1282)
Unity.Netcode.NetworkSceneManager.SynchronizeNetworkObjects (System.UInt64 clientId) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/SceneManagement/NetworkSceneManager.cs:1839)
Unity.Netcode.NetworkConnectionManager.HandleConnectionApproval (System.UInt64 ownerClientId, Unity.Netcode.NetworkManager+ConnectionApprovalResponse response) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Connection/NetworkConnectionManager.cs:823)
Unity.Netcode.ConnectionRequestMessage.Handle (Unity.Netcode.NetworkContext& context) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Messaging/Messages/ConnectionRequestMessage.cs:156)
Unity.Netcode.NetworkMessageManager.ReceiveMessage[T] (Unity.Netcode.FastBufferReader reader, Unity.Netcode.NetworkContext& context, Unity.Netcode.NetworkMessageManager manager) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Messaging/NetworkMessageManager.cs:582)
Unity.Netcode.NetworkMessageManager.HandleMessage (Unity.Netcode.NetworkMessageHeader& header, Unity.Netcode.FastBufferReader reader, System.UInt64 senderId, System.Single timestamp, System.Int32 serializedHeaderSize) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Messaging/NetworkMessageManager.cs:446)
UnityEngine.Debug:LogException(Exception)
Unity.Netcode.NetworkMessageManager:HandleMessage(NetworkMessageHeader&, FastBufferReader, UInt64, Single, Int32) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Messaging/NetworkMessageManager.cs:450)
Unity.Netcode.NetworkMessageManager:ProcessIncomingMessageQueue() (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Messaging/NetworkMessageManager.cs:472)
Unity.Netcode.NetworkManager:NetworkUpdate(NetworkUpdateStage) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkManager.cs:49)
Unity.Netcode.NetworkUpdateLoop:RunNetworkUpdateStage(NetworkUpdateStage) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkUpdateLoop.cs:192)
Unity.Netcode.<>c:<CreateLoopSystem>b__0_0() (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkUpdateLoop.cs:215)

Does anyone know what might be causing this error?

I'd guess the error is on line 54 due to playerName being null but log it to be sure.

Update doesn't look like a good place to pass this as it only needs to be set once (I can't speak for the transform data but you might want to look into network transforms). You could look into passing the name on connection and picking it up in Connection Approval using something like this .

1 Like

The error was indeed on line 54. I solved it by just taking it out of the playerNetworkData struct and just giving it it’s own network variable (I’m pretty new to this and I don’t know how to make it work any other way)

private readonly NetworkVariable<FixedString64Bytes> NetName = new (writePerm: NetworkVariableWritePermission.Owner);

    void Update()
    {
        if (IsOwner) {
            NetName.Value = transform.name;
        } else {
            transform.name = NetName.Value.ToString();
        }
    }

Please avoid putting unrelated data into the same netvar. The player name will change at other times and for other reasons (or not at all) than the x/y position will. So every time your player moves you also send their player name across the network, needlessly! Optimizing bandwidth for a multiplayer game is essential. Every byte counts!

For x/y and scale you can simply rely on NetworkTransform. That leaves you to only sync player name whenever it changes.

1 Like