Search Unity

UNet Optimization tips?

Discussion in 'UNet' started by Doghelmer, Dec 7, 2016.

  1. Doghelmer

    Doghelmer

    Joined:
    Aug 30, 2014
    Posts:
    120
    I've spent the past several weeks converting my game to use UNet multiplayer, and I'm looking to optimize the game to make my bandwidth usage as efficient as possible. But, I haven't been able to track down any guides or concrete information on this sort of thing.

    As someone new to UNet and networking in general, I was wondering if anyone could provide some guidance on the do's and don'ts, or point me in the direction of a decent post or guide.

    Some specific things I was curious about:

    - Is it a good idea to utilize multiple channels of the same type (ex. Reliable Sequenced)? Does this improve performance in some way?
    - When using RPCs and Commands, is best to send data in a format such as byte instead of int or float whenever possible?
    - I read somewhere that changing a syncvar to the exact same value will still cause it to become dirty, and be re-sent, using up more bandwidth. Not sure if this is actually true or not?
    - Is there any way built into Unity of determining approximate bandwidth usage?
     
  2. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Generally speaking, you want to send as less data as possible. For example, if you want to send a player's level, you often times don't need a 32 bit integer. Sometimes a 16 bit 'short' is totally enough, since you probably won't have more than 32767 levels anyway. Even a byte might be enough, since you probably don't have more than 256 levels either.
     
    Last edited: Dec 8, 2016
  3. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    You will find some threads already in the forums if you search for bandwidth.

    UNET automatically does perform some bandwidth optimization measures under the hood (like using bytes for small integers if possible). For example, check out the source code of NetworkWriter.

    You can also check for cases in your project in which you might be able to compress data. For example, see this thread on using the SlimMath library to compress floats when half-precision is sufficient.

    Correct me, but I think this is true. So it might be a good idea to perform a pre-check if the new variable value really is different before updating it on the server.

    Some measurement options are available on tracing packets and such. Unfortunately, however, there is no direct and easy bandwidth measurement option available yet without using external tools. At least, this already has been requested (e.g. here and here). I think it would be a very useful addition for both the profiler and the Unity analytics.

    I would also really like to see more official documentation on best practices for optimizing UNET bandwidth consumption.
     
    Last edited: Dec 9, 2016
  4. Pati-Co

    Pati-Co

    Joined:
    Jan 9, 2014
    Posts:
    56
    Offtopic maybe, cos not about UNET, but in one project I'd minimize client-server traffic a lot by encoding data via bitmask. As result, I send only one 32-bit integer value, instead of whole structure with ~10 different values. You can google for that technique, it's enough popular.
     
  5. Doghelmer

    Doghelmer

    Joined:
    Aug 30, 2014
    Posts:
    120
    I did a test with the Profiler, where I created a simple scene and set a syncvar to a single value on every tick. No change in the syncvar count on the profiler. Then I set the value to a random number on every tick. This caused a profiler's syncvar count to increase. So, I'm guessing that this may not actually be an issue?
     
  6. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    Hmm, okay. I had run some tests for SyncVars with hook functions. At least, it seems that the hook functions are called on the clients even in such cases when the new value are the same as the old ones. Maybe you can also do some testing on SyncVars with hook functions so we can get some more insights here.
     
    Last edited: Dec 10, 2016
  7. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    I've got another one:

    If I'm sending a ton of updates that are all the same size will I benefit from sending them on a separate channel with packet size set to exactly enough to hold a single state update?
     
  8. Doghelmer

    Doghelmer

    Joined:
    Aug 30, 2014
    Posts:
    120
    Another issue I'm confused about right now: Sometimes, an object's NetworkTransform sends out Syncvars even when the object is completely motionless. But only sometimes. I can't find any rhyme or reason to this -- I can literally have two objects in the scene that are entirely the same in every way in the inspector, yet one of them is causing the profiler's syncvar count to increase while the other is not (as indicated by enabling and disabling the two objects). In one instance, the issue stopped occurring when I used "Sync Transform" instead of "Sync Rigidbody 2D". Yet, I found another instance where the issue occurred with an object using Sync Transform. The issue stops occurring if I set the movement threshold to a much higher amount. Very weird.

    Any ideas on that one?
     
    Last edited: Dec 10, 2016
  9. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    The best optimisation is really waiting as long as you can before sending stuff, because the packet overhead is usually the worst thing about it, not the actual data you're sending.

    Consider sending a single byte? you're actually sending a single byte + 48+ bytes of packet overhead, so sending 2 bytes (or two auto optimised ints) will result in much better use of bandwidth.

    So basically I split my stuff between important and not important. Not important can wait for a regular larger packet, while important must go pretty much right away. That was a reasonable optimisation back when I used Unet.
     
  10. Doghelmer

    Doghelmer

    Joined:
    Aug 30, 2014
    Posts:
    120
    Has anyone written/spotted a decent summary of how to best utilize the different channel types? The only article of substance I've come across on the topic is this one.