Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Unity Multiplayer Custom serialization and SetDirtyBit

Discussion in 'Connected Games' started by glitchers, Jul 23, 2015.

  1. glitchers

    glitchers

    Joined:
    Apr 29, 2014
    Posts:
    48
    Hi,

    I've been trying to find some information about dirty bit in regards to custom serialization. As far as I can tell SetDirtyBit works only if you use SyncVars.

    Am I missing something or should I implement this myself?

    Thank you
     
  2. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
  3. glitchers

    glitchers

    Joined:
    Apr 29, 2014
    Posts:
    48
    I have read that page from the manual, I was looking for some clarification on it's implementation when not using SyncVars.

    From what I understand, every NetworkBehaviour has syncVarDirtyBits, but only if you use SyncVars it is written to automatically.

    Am I able to use it as my custom dirty bit mask or will it's value be overwritten automatically?
     
  4. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    SyncVar accessor properties write to the dirty mask, and it is set to zero after an update is sent. Those are the only built-in interactions.
     
    glitchers likes this.
  5. Mr-Slat

    Mr-Slat

    Joined:
    Jan 25, 2013
    Posts:
    2
    For anyone with this problem here go's a solution. It's kinda bad but it works (NOTE : Haven't tested the code but it should work. If you have any problems just comment and i'll fix it) :

    Code (CSharp):
    1.  
    2. public class Player : NetworkBehaviour
    3. {
    4.     public delegate void PlayerEventHandler(Player sender);
    5.  
    6.     public event PlayerEventHandler OnCanBeDamagedChanged;
    7.  
    8.     public bool canBeDamaged = true;
    9.  
    10.     protected virtual void Start()
    11.     {
    12.         OnCanBeDamagedChanged += OnCanBeDamagedHasChanged;
    13.     }
    14.  
    15.     protected virtual void OnDestroy()
    16.     {
    17.         OnCanBeDamagedChanged -= OnCanBeDamagedHasChanged;
    18.     }
    19.  
    20.     //Press A to change canBeDamaged value
    21.     protected virtual void Update()
    22.     {
    23.         if (!isServer)
    24.             return;
    25.  
    26.         if (Input.GetKeyDown(KeyCode.A))
    27.             CanBeDamaged = !canBeDamaged;
    28.     }
    29.  
    30.    public override bool OnSerialize(NetworkWriter writer, bool initialState)
    31.     {
    32.         base.OnSerialize(writer, initialState);
    33.  
    34.         writer.Write(canBeDamaged);
    35.  
    36.         return true;
    37.     }
    38.  
    39.     public override void OnDeserialize(NetworkReader reader, bool initialState)
    40.     {
    41.         base.OnDeserialize(reader, initialState);
    42.  
    43.         bool    _canBeDamaged   = reader.ReadBoolean();
    44.  
    45.         if (_canBeDamaged != canBeDamaged)
    46.         {
    47.             canBeDamaged = _canBeDamaged;
    48.  
    49.             if (OnCanBeDamagedChanged != null)
    50.                 OnCanBeDamagedChanged(this);
    51.         }
    52.     }
    53.  
    54.     protected virtual void OnCanBeDamagedHasChanged()
    55.     {
    56.         //Code for logic when can be damaged
    57.         //changes
    58.         Debug.Log("Player : " + gameObject.name + ", can be damaged has been changed to " + canBeDamaged.ToString());
    59.     }
    60.  
    61.     //Use this implementation to make this NetworkBehaviour
    62.     //send a new update if canbeDamaged changes
    63.     //(NOTE : The "set" implementation should run on the Server)
    64.     public bool CanBeDamaged
    65.     {
    66.         get { return canBeDamaged; }
    67.  
    68.         set
    69.         {
    70.             if (canBeDamaged == value)
    71.                 return;
    72.  
    73.             canBeDamaged = value;
    74.  
    75.             if (isServer)
    76.                 SetDirtyBit(1u);
    77.  
    78.             if (OnCanBeDamagedChanged != null)
    79.                 OnCanBeDamagedChanged(this);
    80.         }
    81.     }
    82. }
    When you set "CanBeDamaged", to a different value, then it will make the NetworkBehaviour send a new update, forcing it to serialize.

    if you want to listen player canBeDamaged from outside the Player class then use the event :

    something like :

    Code (CSharp):
    1.  
    2. public class Test : MonoBehaviour
    3. {
    4.     private Player player;
    5.  
    6.     private void Start()
    7.     {
    8.         player = GameObject.FindObjectOfType<Player>();
    9.  
    10.         if (player != null)
    11.         {
    12.             //Assigning Player OnCanBeDamagedChanged event
    13.             player.OnCanBeDamagedChanged += OnPlayerCanBeDamagedChanged;
    14.         }
    15.     }
    16.  
    17.     private void OnDestroy()
    18.     {
    19.         if (player != null)
    20.         {
    21.             player.OnCanBeDamagedChanged -= OnPlayerCanBeDamagedChanged;
    22.             player = null;
    23.         }
    24.     }
    25.  
    26.     private void OnPlayerCanBeDamagedChanged(Player sender)
    27.     {
    28.         //Code when player can be damaged changes.
    29.         Debug.Log("Player Can Be Damaged = " + sender.canBeDamaged.ToString());
    30.     }
    31. }
    32.  
    (NOTE : For OnSerialize to work properly you can't have any SyncVar fields. The Documentation explains it further :
    "...If a class has SyncVars, then an implementation of this function and OnDeserialize() are added automatically to the class. So a class that has SyncVars cannot also have custom serialization functions…" From : https://docs.unity3d.com/ScriptReference/Networking.NetworkBehaviour.OnSerialize.html )

    Hope this helps.
     
    Last edited: Sep 16, 2018