Search Unity

Why do children not inherit their parents NetID?

Discussion in 'Multiplayer' started by Salmjak, Feb 17, 2016.

  1. Salmjak

    Salmjak

    Joined:
    Nov 25, 2014
    Posts:
    20
    I noticed when trying to add a gameobject to the hand of a player that it will throw a NullReferenceException (when trying to [ClientRpc] the "parenting") because the hand is not spawned (or is it, but lack a unique netID?).

    How come? What is the reason for this? I can see the hand when running the game, so the gameobject itself is instantiated and all children update as they should (which should suggest that they do exist on both client and server), but it's children are technically not instantiated on the server or are they but lack a netID? Why don't they inherit some form of netID so that they can be referred to? Is it due to technical/performance issues or just something the devs didn't think of?

    Obviously this causes a problem because a prefab should only have one NetworkIdentity.
     
    Last edited: Feb 17, 2016
  2. foxifi

    foxifi

    Joined:
    Dec 20, 2015
    Posts:
    55
    I'd like to see some input on this from someone that knows, but my player prefab is many different children under the player parent as well.

    If you don't mind, what is the reason you want to have netId's on the children? In mine, all parts of my character (granted it is 2D) are visible on client and server and (I wrote my own synchronization for movement) all parts move and sync properly without any networking whatsoever on the children. The parent has ALL scripts that are NetworkBehaviors, and only parent's have Network Identity's.
     
  3. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    If children inherit parent's net ID, it will cause conflicts when the client wants to know who exactly is the parent or child? And who to send messages/events/updates to?
     
  4. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    In response to the OP...it depends on how you want to accomplish this. Let's say the player wants to pick up a rock that was a part of the scene when they were spawned.
    1. Have the Client send a Command to the server "requesting" to pick up the rock. To identify the rock, use it's netId and on the server use NetworkServer.FindLocalObject().
    2. The server receives the Command and checks to see if the player can pick up the rock.
    3. If the player can pick up the rock the server can execute code to make it happen. Send a message back to the player making them execute an animation that makes them bend over and make a picking up motion.
    4. At a certain point in the animation, include an Animation Event that is only executed on the server that makes the rock become a child of an Empty GameObject positioned on the player's hand (bone).
    5. Since the rock belongs to the server, the server can dictate it's position and rotation.
    6. The rest of the logic is up to you. For example you could put a script on the rock that updates it's position and rotation once it has a parent. Make sure the rock has some component (like the NetworkTransform) that synchronizes its position & rotation to ALL clients.
     
  5. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    So that's how NetworkServer.FindLocalObject() works. And the Animation event, both of which I never knew.
     
  6. notseanr

    notseanr

    Joined:
    Jan 15, 2016
    Posts:
    22
    The NetworkId is used to identify the NetworkIdentity across the network. It is included in network packets, then used to route messages to the correct object. So NetworkBehaviour scripts must be on the same (root ) object with the NetworkIdentity so that messages can be routed to it.

    But a networkId is not enough information to route to a child within a heirarchy of objects. To do that there would need to be more information in network messages, such as a child Index. This could be used to index into GetComponentsInChildren<NetworkBehaviour>() to find the right sub-object to route to.

    However, the trouble with a child index is that the hierarchy is not guaranteed to be stable, or to be the same on the server and client, so messages could get routed to the wrong place or to missing objects. So this system would be fragile, especially in cases where the hierarchy changes over time - such as dropping and pickup up networked objects.

    This is made even more complex by the Unity Prefab system. If NetworkIdentities can be on sub-objects within a hierarchy, then they can be on sub-objects within a prefab. This makes spawning and joining a game in progress difficult.

    If a prefab has a NetworkIdentity on a sub object, and it is spawned on a client when joins a game, the sub-object would be created with the prefab on the client. But what if the hierarchy has changed on the server since the object was created, such as wheel being blown off? Now the client spawns with the wheel still on the object, since it came from the prefab, and there is potentially another wheel somewhere in the world.. with the same NetworkId??

    And dont even get started with nested prefabs.
     
  7. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Any GameObject can only have ONE NetworkIdentity. This includes the GameObject's children.
     
  8. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    @notseanr Living it up to your name, I see.

    @DRRosen3 You know it is possible to set the transform's parents of an object to an object with NetworkIdentity, and then add a NetworkIdentity to the child, creating undefined behaviors even though they all work normally? Just saying...
     
  9. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Do it and you'll get a warning @asperatology...and IIRC somewhere in this forum someone in the Unity Technologies team mentioned making it impossible to do and/or adding a full blown error.
     
  10. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    Well, they sort of failed, because I can do it in 5.3.2p4 without warnings. I don't know what's going on with it, and I'm not bothering with it in my projects anyway, except for experiments and test projects.

    But there are errors that would refer to things not related to game objects with NetworkIdentity whose child game objects have NetworkIdentities attached. Nobody could even come up with the notion it may have been child game objects with NetworkIdentities that's causing the problem, if you read those errors spewing out from it.