Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

[NetCode] [ECS] Send list in Rpc?

Discussion in 'Data Oriented Technology Stack' started by paolo_simone_enovia, Feb 5, 2020.

  1. paolo_simone_enovia


    Jan 17, 2020

    I would like to send some metadata from server to client after the connection. This metadata doesn't change during the game, so it would make sense to use a Rpc once at the beginning.

    The problem is that the metadata contains a list with a variable number of elements.
    From this thread it seems that the correct way to include a list in a component (and hence in a IRpcCommand?) would be to use a DynamicBuffer, but it's not clear how.
    I have naively tried something like this:
    Code (CSharp):
    2. using Unity.Burst;
    3. using Unity.Networking.Transport;
    4. using Unity.NetCode;
    5. using Unity.Entities;
    6. [BurstCompile]
    7. public struct MetadataRpc : IRpcCommand
    8. {
    9.    public int Scalar;
    10.    public DynamicBuffer<IntElement> Numbers;
    11.    public void Serialize(DataStreamWriter writer)
    12.    {
    13.        writer.Write(Scalar);
    14.        writer.Write(Numbers.Length);
    15.        foreach(IntElement n in Numbers)
    16.        {
    17.            writer.Write(n.Value);
    18.        }
    19.    }
    20.    public void Deserialize(DataStreamReader reader, ref DataStreamReader.Context ctx)
    21.    {
    22.        Scalar = reader.ReadInt(ref ctx);
    23.        var length = reader.ReadInt(ref ctx);
    24.        for (int i = 0; i < length; i++)
    25.        {
    26.            Numbers.Add(new IntElement { Value = reader.ReadInt(ref ctx) });
    27.        }
    28.    }
    29.    [BurstCompile]
    30.    private static void InvokeExecute(ref RpcExecutor.Parameters parameters)
    31.    {
    32.        RpcExecutor.ExecuteCreateRequestComponent<MetadataRpc>(ref parameters);
    33.    }
    34.    public PortableFunctionPointer<RpcExecutor.ExecuteDelegate> CompileExecute()
    35.    {
    36.        return new PortableFunctionPointer<RpcExecutor.ExecuteDelegate>(InvokeExecute);
    37.    }
    38. }
    39. public struct IntElement : IBufferElementData
    40. {
    41.    public int Value;
    42. }
    43. class MetadataRequestRpcCommandRequestSystem : RpcCommandRequestSystem<MetadataRpc>
    44. {
    45. }
    But I have problems in creating the DynamicBuffer on server... from the documentation seems that it can only be created attached to an entity?
    Probably I'm missing something, but even if I manage to instantiate a DynamicBuffer then I have no idea if it would be actually serialized/deserialized correctly when sent over Rpc?

    So... is there a way to send an Rpc containing a dynamic sized list?
  2. Quinnius


    Jan 29, 2020
    I'm attaching a DynamicBuffer to the IRpcCommand but it never shows up on the client, and I can't find any examples of sending the DynamicBuffer across the network.

    Is this the wrong approach, or just not well documented yet?
  3. Brendon_Smuts


    Jun 12, 2017
    The RPC command is a component and has the same restrictions. You cannot have a dynamic buffer reference inside a component. I suggest taking a look at Unity’s new FixedListByteXXX structures in Unity.Collections. These are in place arrays that can be stored inside components. Be warned they are not resizable and used incorrectly can create very large components as the buffer they wrap around is inside the structure and not allocated on the heap. If you have a fixed upper limit on the size these should work for you.
    paolo_simone_enovia likes this.