Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Unity Multiplayer How do you use SetDirtyBit ?

Discussion in 'Multiplayer' started by Paradoks, Jul 9, 2018.

  1. Paradoks

    Paradoks

    Joined:
    Oct 13, 2009
    Posts:
    436
    Hi,

    It is a pretty newbie question, i don't really understand how to use it as the manual don't say much.
    What is this parameter "Bit mask to set" ?
    Why sometimes people put parametters sometimes not ?

    thx for you answers.
     
  2. Paradoks

    Paradoks

    Joined:
    Oct 13, 2009
    Posts:
    436
    @aabramychev
    Someone from unity at least please, you make a tool, and dont let informations on manual.
     
  3. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    574
    I'm sorry, but I don't understand what are you talking about. What SetDirtyBit do you want to set and where? :(
     
  4. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    4,281
    SetDirtyBits sets NetworkBehaviour.syncVarDirtyBits:
    upload_2018-7-21_13-13-11.png

    UNET only serializes your components if at least one of them is dirty.

    If you are wondering what this magic is for: let's say you have 3 variables in your Player script that you want to sync over the network. OnSerialize gets called, then you sync all 3 of them. OnSerialize gets called again, but maybe only 1 of them changed, so there's no point in syncing all 3 of them again, or you'd waste bandwidth. You only want to sync the changed one. So in order to know which things changed, you always also send the dirty bit mask. For example, if the first bit is 1, then your first value changed. If the second bit is 1, then your second value changed, etc.
     
  5. Paradoks

    Paradoks

    Joined:
    Oct 13, 2009
    Posts:
    436
    That's a good explanation thx.
    But how do you practically use it ?
    Let's take this scenario:

    Code (CSharp):
    1.  
    2.  
    3. [SyncVar]
    4. public int hp= 100;
    5.  
    6. [SyncVar]
    7. public int mp= 100;
    8.  
    9. [SyncVar]
    10. public int gold= 100;
    11.  
    12. void Start(){
    13.  
    14.     ChangeHp(9999);
    15. }
    16.  
    17. void ChangeHp(int newHp){
    18.  
    19.     hp = newHp;
    20. }
    21.  
    All the syncVars should be sent right ?
    So now how do you change only the hp one ? before the "all sync" get triggered ?
     
  6. Eagles_rule_der

    Eagles_rule_der

    Joined:
    Oct 22, 2017
    Posts:
    1
    Hi! Was looking for something else when I stumbled on this and wanted to help out :)

    In this particular example the [SyncVar] attribute manages the bitmasks for you, and will only send an update for HP such that you shouldnt have any real need to even call SetDirtyBit()
    SetDirtyBit() itself is really only needed in the event that you make your own OnSerialize and OnDeserialize methods.

    Even as a simple example
    Code (CSharp):
    1. public override bool OnSerialize(NetworkWriter writer, bool initialState)
    2. {
    3. if(initialState || hpNeedsUpdate)
    4. writer.write(hp)
    5.  
    6. return initialState || hpNeedsUpdate;
    7. }
    Edit: To Clarify; SetDirtyBit doesnt even actually relate to which variables need updating.
    SetDirtyBit() says in essence "If you are on channel 1, trigger an OnSerialise"
     
    Last edited: Apr 28, 2019
  7. craig4android

    craig4android

    Joined:
    May 8, 2019
    Posts:
    124
    will dirty bits be reset automatically after serialize?

    Edit: just tested and it does
     
  8. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    763
    @Paradoks you usually don't need to do anything with SetDirtyBits, it is set automatically whenever you set any syncvar.

    In your example:

    Code (CSharp):
    1.  
    2. [SyncVar]
    3. public int hp= 100;
    4.  
    5. [SyncVar]
    6. public int mp= 100;
    7.  
    8. [SyncVar]
    9. public int gold= 100;
    10.  
    11. void Start(){
    12.     ChangeHp(9999);
    13. }
    14.  
    15. void ChangeHp(int newHp){
    16.  
    17.     // This line will automatically call SetDirtyBit(1)
    18.     hp = newHp;
    19. }
    20.  
    When the object is spawned the first time, all variables are sent.

    But if you happen to call ChangeHP at a later time, then the line
    Code (csharp):
    1. hp=newHP;
    will automatically call
    Code (csharp):
    1. SetDirtyBit(1)
    This sorcery is done by the weaver. It will call it with parameter 1 to indicate that the first variable is dirty. When you change mp, it would call it with 2, When you change gold, it will call it with 4.

    Then in the next sync interval, Mirror and UNET will look at which bits are set, and sync those variables.

    So basically you almost never want to call SetDirtyBits yourself, just set your syncvars.
     
    illadro likes this.