Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved How to send a string array in an RPC?

Discussion in 'Netcode for GameObjects' started by lavagoatGG, Jul 27, 2023.

  1. lavagoatGG

    lavagoatGG

    Joined:
    Apr 16, 2022
    Posts:
    226
    I get an error that says that string or FixedString128Bytes can't be serialized. How can I send it in a RPC? Do I have to create a serializer?
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    638
    Either should be working, in case it matters what NGO version are you using?
     
  3. lavagoatGG

    lavagoatGG

    Joined:
    Apr 16, 2022
    Posts:
    226
    1.2.0
     
  4. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    638
    I tried 1.5.1 and then downgraded to 1.2.0 and saw no issues.

    This is the code I used:
    Code (CSharp):
    1.     SendStringServerRpc(new FixedString128Bytes(OwnerClientId.ToString()), OwnerClientId.ToString());
    2.  
    3.     [ServerRpc]
    4.     private void SendStringServerRpc(FixedString128Bytes fixedString, string myString)
    5.     {
    6.         Debug.Log($"SendStringServerRpc: fixedString {fixedString} myString {myString}");
    7.  
    8.         SendStringClientRpc(fixedString, myString);
    9.     }
    10.  
    11.     [ClientRpc]
    12.     private void SendStringClientRpc(FixedString128Bytes fixedString, string myString)
    13.     {
    14.         Debug.Log($"SendStringClientRpc: fixedString {fixedString} myString {myString}");
    15.     }
     
  5. lavagoatGG

    lavagoatGG

    Joined:
    Apr 16, 2022
    Posts:
    226
    Can you send an array of strings?
     
  6. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    638
    Ah sorry no, I missed the array part. You could wrap them in a INetworkSerializable struct or going by the error you should be able to write extension methods to handle the serialisation.
     
  7. lavagoatGG

    lavagoatGG

    Joined:
    Apr 16, 2022
    Posts:
    226
    Okay. Can you give me an example how to do that?
     
  8. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    638
    I'm not sure about the extension methods as I don't use them but this may work for a struct:

    Code (CSharp):
    1. public struct Strings : INetworkSerializable
    2. {
    3.     string[] myStrings;
    4.  
    5.     public Strings(string[] myStrings)
    6.     {
    7.         this.myStrings = myStrings;
    8.     }
    9.  
    10.     public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    11.     {
    12.         if(serializer.IsWriter)
    13.         {
    14.             FastBufferWriter fastBufferWriter = serializer.GetFastBufferWriter();
    15.             fastBufferWriter.WriteValueSafe(myStrings.Length);
    16.  
    17.             for (int i = 0; i < myStrings.Length; i++)
    18.             {
    19.                 fastBufferWriter.WriteValueSafe(myStrings[i]);
    20.             }
    21.         }
    22.  
    23.         if(serializer.IsReader)
    24.         {
    25.             FastBufferReader fastBufferReader = serializer.GetFastBufferReader();
    26.             fastBufferReader.ReadValueSafe(out int length);
    27.  
    28.             myStrings = new string[length];
    29.  
    30.             for (int i = 0; i < length; i++)
    31.             {
    32.                 fastBufferReader.ReadValueSafe(out myStrings[i]);
    33.             }
    34.         }
    35.     }
    36.  
    37.     public string[] MyStrings { get => myStrings; set => myStrings = value; }
    38. }
     
    lavagoatGG likes this.
  9. lavagoatGG

    lavagoatGG

    Joined:
    Apr 16, 2022
    Posts:
    226
    Thank you, it works!
    by the way, what's on your picture?
     
  10. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    638
    No problem. That pic is someone killing N-K Necrosis for me in Star Wars Galaxies, as I'm not helping I guess I was on a crafter toon. That game had some cool animations, she's guiding the lightsaber in front of her with her hand. :)
     
    lavagoatGG likes this.
  11. FelixNicol

    FelixNicol

    Joined:
    Jul 18, 2021
    Posts:
    5
    Hi,thanks both of you this was very helpful!

    Here I made it into an extension for my needs based on cerestorm solution. I tried to make it generic, but it was only working with INetworkSerialisable objects. Maybe I was missing something.

    Code (CSharp):
    1.     public static class FastBufferExtension
    2.     {
    3.         public static void WriteArraySafe(this FastBufferWriter writer, FixedString64Bytes[] array)
    4.         {
    5.             if (array == null) array = new FixedString64Bytes[0];
    6.             writer.WriteValueSafe(array.Length);
    7.             for (int i = 0; i < array.Length; i++)
    8.             {
    9.                 writer.WriteValueSafe(array[i]);
    10.             }
    11.         }
    12.  
    13.         public static void ReadArraySafe(this FastBufferReader reader, out FixedString64Bytes[] array)
    14.         {
    15.             reader.ReadValueSafe(out int length);
    16.             array = new FixedString64Bytes[length];
    17.             for (int i = 0; i < length; i++)
    18.             {
    19.                 reader.ReadValueSafe(out array[i]);
    20.             }
    21.         }
    22.     }

    Thank you again!
     
  12. b4guw1x

    b4guw1x

    Joined:
    Apr 16, 2020
    Posts:
    29
    I will post another solution to here. Instead of creating a class and make it serializable, we can use network lists.


    Code (CSharp):
    1. private NetworkList<FixedString128Bytes> _playerNamesInOrder;
    2.  
    3. private void Awake()
    4. {
    5.       _playerNamesInOrder = new NetworkList<FixedString128Bytes>(readPerm: NetworkVariableReadPermission.Everyone);
    6. }
    But be aware, don't initialize network lists on decleration, it will cause memory leak. Instead initialize it on awake.