Search Unity

SyncVar doesn't work with inheritance

Discussion in 'Multiplayer' started by PhilSA, Aug 7, 2016.

  1. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    After dozens of hours of pure suffering, I found out there's some kind of problem with syncvars and inheritance. I'm using Unity 5.4.0f3

    From the tests I've made, it looks like some SyncVar types (like GameObject in my case) will not automatically synchronize with clients upon connecting to a game if they are in a parent class that also has SyncVars.

    For example:
    Code (CSharp):
    1.  
    2. public class ClassA : NetworkBehaviour
    3. {
    4.     [SyncVar]
    5.     public string name;
    6.     [SyncVar]
    7.     public GameObject testObject;
    8. }
    9.  
    10. public class ClassB : ClassA
    11. {
    12.     [SyncVar]
    13.     public GameObject otherTestObject;
    14. }
    When a new client enters the game where there is already a ClassB object spawned, "name" and "otherTestObject" will get synced automatically on that object, but "testObject" will not. It will only get synced when it becomes dirty later on, after the client joined a game. However, if I make that object just ClassA instead of its child class, the GameObject SyncVar gets synced properly when the player joins

    I've seen people reporting on something similar to this issue up to almost a year ago:
    http://forum.unity3d.com/threads/syncvar-polymorphism-issue.385491/
    http://forum.unity3d.com/threads/lots-of-unet-bugs.357990/
    http://forum.unity3d.com/threads/syncvar-properties-in-parent-and-child-classes.327553/

    Has Unity made any progress on this?
     
    Last edited: Aug 10, 2016
    nonom likes this.
  2. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    I am not 100% sure but I *think* SyncVars must be primitive types like ints/floats/bytes/bools etc. I do not think objects can be SyncVars.

    It says here "Simple Values" can be SyncVars... which I *think* is primitive. https://docs.unity3d.com/ScriptReference/Networking.SyncVarAttribute.html

    If you want to Sync the reference to an object what I have done is Sync the UNET NetworkIdentity ID which is a primitive number that CAN be a SyncVar. Then lookup and find that object locally on each client based on the ID.
     
  3. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    The GameObjects do get synced properly through SyncVar when not using inheritance, or when the syncVar gets dirty after a client has joined (it's a secret feature!). But, it'd be interesting to see if I still get this inheritance problem if I use NetworkInstanceId instead.... I'll try to make a test later
     
  4. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    OK well I'm curious. Let us know what your testing reveals.

    If you can't get it to work then you can fall back on the NetworkIdentity.ID syncing as a solution... which is a bit more code but should work.
     
  5. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    I ended up testing with NetworkInstanceID instead of GameObject and it did work correctly. I'm guessing there's something in the GameObject spawning/initialization order of execution that made it null or not findable at the start of the client
     
    Last edited: Aug 10, 2016
    nonom likes this.
  6. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    nonom likes this.