Search Unity

Resolved [NetCode] Problems with multiple input buffers and quantization

Discussion in 'NetCode for ECS' started by coffeecatcoding, Sep 28, 2020.

  1. coffeecatcoding

    coffeecatcoding

    Joined:
    Sep 28, 2020
    Posts:
    10
    Hello,

    first of all I'm a big fan of the Unity DOTS and thankful for everyone working towards making it a great experience for all game developers;

    Now to a problem I can't seem to solve on my own;

    Description:

    [EDIT1]:
    Using just one buffer for all input works with manually multiplying/dividing by 1000 and casting/storing int, I haven't tried using GhostfieldAttribute with only one buffer yet, but to me it seems like there is a problem with multiple buffers on an entity;

    [EDIT2]:
    Seems like I ran into multiple problems at once;
    The explanation of why adding two buffers server side did not work is that the second buffer invalidated the first one.
    https://docs.unity3d.com/Packages/c...ic_buffers.html#buffer-reference-invalidation

    [EDIT3]:
    I had a wrong grasp of how to use the [GhostField] attribute, I was using it on the values inside my ICommandData input struct which is incorrect.
    If you want to quantize input you need to implement custom serialization as mentioned here:
    https://docs.unity3d.com/Packages/c...nual/command-stream.html#manual-serialization
    The [GhostField] attribute has to be put on the values that you want to include in your snapshot, in my case the mouse input is used to calculate rotation angles (float) for camera rotation, since I want to include the rotation angles in my snapshot I need to quantize them using [GhostField(Quantization=1000)] because they are float types.
    Everything works as expected now.

    [ORIGINAL]:
    I used the samples provided here: https://github.com/Unity-Technologies/multiplayer
    to create a Command struct for keyboard input just like in the NetCube sample and it works great;
    Now I created a second Command struct for mouse input and added the neccesary components and buffers on client and server side;

    Code (CSharp):
    1.     public struct MouseInput : ICommandData
    2.     {
    3.         public uint Tick { get; set; }
    4.         public float horizontal;
    5.         public float vertical;
    6.         public float mouseScrollDelta;
    7.     }

    When I enter playmode, the console prints out errors for this struct and the generated serializer:
    Code (CSharp):
    1. ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
    2. Unity.Networking.Transport.DataStreamReader.ReadBytes (System.Byte* data, System.Int32 length) (at Library/PackageCache/com.unity.transport@0.4.1-preview.1/Runtime/DataStream.cs:624)

    I understand that float values should be quantized to save bandwidth, however if I add the
    [GhostField(Quantization = 1000)]
    attribute to all three float values, the generated serializer methods are empty and the inputbuffer data is not being send to the server, also, the other input buffer for the keyboard input which worked before now stays at size 0 and stops working (server world);

    I have tried to convert the float fields to int and multiply/divide by 1000 manually without success;
    I have read the manual and it says quantization is mandatory for float types, so my guess is that I am just using the Ghostfield attribute incorrectly;
    https://docs.unity3d.com/Packages/com.unity.netcode@0.4/manual/ghost-snapshots.html

    Thanks for your help in advance;
    Special thanks to the people who helped me understand these concepts better in the multiplayer discussion thread.
     
    Last edited: Oct 5, 2020
    adammpolak likes this.
  2. adammpolak

    adammpolak

    Joined:
    Sep 9, 2018
    Posts:
    450
    @coffeecatcoding do you mind posting your final ICommandData structs and the Input system that takes in the data? I am facing similar problems and can't figure it out :-(