-
Notifications
You must be signed in to change notification settings - Fork 459
Description
Description
In a distributed authority setup, I noticed that the NetworkList sometimes goes out of sync. For example, I have a private NetworkList called connectedPlayers. I built the game and ran three instances, where Client 1 was the session owner. Only the session owner is allowed to update connectedPlayers.
For each client connection, I added the new PlayerConnection from the session owner's side. Initially, it logged correctly for the first two clients as:
SceneEventType: SynchronizeComplete | ConnectedPlayerClientIds: 1,3,2
However, for the third client, the log showed:
SceneEventType: SynchronizeComplete | ConnectedPlayerClientIds: 1,3,2,3,2
indicating that some entries were duplicated. this not happens often(mostly happens when I run multiple built instances simultaneously, causing my PC's CPU usage to reach 100%.) so it's hard to reproduce but it makes me feel that NetworkList is unreliable to use. Is there any alternative of NetworkList? or if not could this be indicating bug in NGO?
public class NetworkPlayerManager : NetworkBehaviour
{
private NetworkList<PlayerConnection> connectedPlayers = new();
public override void OnNetworkSpawn()
{
NetworkManager.SceneManager.OnSceneEvent += OnSceneEvent;
}
private void OnSceneEvent(SceneEvent sceneEvent)
{
Debug.Log($"SceneEventType: {sceneEvent.SceneEventType} | ConnectedPlayerClientIds: {string.Join(",", connectedPlayers.ToList().Select(c => c.ClientId))}")
}
}
using System;
using Assets.Scripts.Tools;
using Unity.Collections;
using Unity.Netcode;
namespace Assets.Scripts
{
public struct PlayerConnection : INetworkSerializable, IEquatable<PlayerConnection>
{
public ulong ClientId;
public FixedString64Bytes PlayerId;
public FixedString64Bytes PlayerName;
public NetworkObjectReference NetworkPlayerRef;
public PlayerConnection(
ulong clientId,
FixedString64Bytes playerId,
FixedString64Bytes playerName,
NetworkObjectReference networkPlayerRef)
{
ClientId = clientId;
PlayerId = playerId;
PlayerName = playerName;
NetworkPlayerRef = networkPlayerRef;
}
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref ClientId);
serializer.SerializeValue(ref PlayerId);
serializer.SerializeValue(ref PlayerName);
serializer.SerializeValue(ref NetworkPlayerRef);
}
public bool Equals(PlayerConnection other)
{
return ClientId == other.ClientId &&
PlayerId == other.PlayerId &&
PlayerName == other.PlayerName &&
NetworkPlayerRef.Equals(other.NetworkPlayerRef);
}
}
}
Environment
- Unity Version: Unity 6 (6000.0.32f1)
- Netcode Version: [2.2.0]