Search Unity

NetworkList inside custom NetworkVariable type?

Discussion in 'Netcode for GameObjects' started by Anxo, Nov 25, 2022.

  1. Anxo

    Anxo

    Joined:
    Jan 7, 2014
    Posts:
    13
    Let's say a player has guns. But We do not know how many guns the player will have, so each player can have a list of guns, but there is also multiple players who have stats that need to be updated like heath, team so on. I want to nest a Networklist inside of a Player which is a network variable. It appears that Networklist is not supported in the serialization.

    Code (CSharp):
    1. public struct PlayerStats: INetworkSerializable
    2. {
    3.    private Vector3 PlayerPosition;
    4.    public Quaternion PlayerRotation;
    5.    public NetworkList<PlayerGunPack> PlayerGuns;
    6.    public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    7.    {
    8.       serializer.SerializeValue(ref ShipPosition);
    9.       serializer.SerializeValue(ref ShipRotation);
    10.       serializer.SerializeValue(ref PlayerGunPack); // <== not supported
    11.    }
    12. }
    13.  
    14. public struct PlayerGunPack: INetworkSerializable ,IEquatable<PlayerGunPack>
    15. {
    16.    public int GunIndex;
    17.    public int GunType;
    18.  
    19.    public PlayerGunPack(int incIndex, int inctype)
    20.    {
    21.       GunIndex= incIndex;
    22.       GunType= incType;
    23.    }
    24.    public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    25.    {
    26.       throw new System.NotImplementedException();
    27.    }
    28.  
    29.    public bool Equals(PlayerGunPack other)
    30.    {
    31.       return GunIndex== other.GunIndex&& GunType.Equals(other.GunType);
    32.    }
    33.  
    34.    public override bool Equals(object obj)
    35.    {
    36.       return obj is PlayerGunPack other && Equals(other);
    37.    }
    38.  
    39.    public override int GetHashCode()
    40.    {
    41.       return HashCode.Combine(GunIndex, GunType);
    42.    }
    43. }
    44.  
    Please note that this is not actually my example as I am not dealing with player guns, I just tried to pick an example that is easy to understand.

    My plan would be to use it like so.
    Code (CSharp):
    1. public class Player : NetworkBehaviour (){
    2.      private NetworkVariable<PlayerStats> playerStats = new NetworkVariable<PlayerStatus> .... // constructor stuff
    3.  
    4.  
    5. }

    Thank You.
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,956
    You don't actually have to nest the guns list in the PlayerStats. In fact, doing so may be inefficient because whenever any value of PlayerStats changes, the whole struct gets serialized and sent across the network.

    Best to keep PlayerGuns as a separate list. But if you do want a list, just use a regular List<> and serialize that, after all, you're already creating a custom serialized struct.

    But it may be more efficient to synchronize this list with the server through RPCs. For example, if the list frequently contains dozens of entries, but only very few of those entries change most of the time, it'll likely be more efficient (assuming Netcode sends the entire list, not just what has changed - don't know if that holds true) to implement this as RPCs via AddGunServerRpc and RemoveGunServerRpc.
     
    trombonaut likes this.