Nested NetworkObjects on players
The doc page on NetworkObject parenting describes a very common situation in which one parents an item (say a picked up weapon) to part of the player (say the hand). However, this requires the player's hands to be NetworkObjects themselves (as shown in the diagram on that doc page), and it currently seems like this is unachievable except if all players are scene objects (which is obviously undesirable for games with many players or that allow players to connect asynchronously). Trying to spawn the hands after spawning the players is not allowed by Netcode, even when the hands have been added as separate prefabs in the NetworkManager's prefab list.
Is there currently any way to parent NetworkObjects to parts of the player, without making all players scene objects?
You should be able to spawn the hands after the player if the hands are separate NetworkObjects and then you can reparent the hands under the player object. It sounds like you tried that but it failed, do you remember why that didn't work?
On the server it works fine, but on the client it throws an error that you cannot reparent a NetworkObject to a non-NetworkObject. It might work to go down the entire hierarchy of the player object and make every bone a NetworkObject, but that seems overkill (and also does not match the documentation).
To be clear, I am allowed to reparent the spawned hand objects under the player object's root, but that's of course not where the hands should go.
I get that it works this way in general, because a non-networkobject child might not exist on all clients, but maybe this can be allowed to work for (player) prefabs? Or perhaps there already is a way to achieve this but I'm missing it?
Same issue for me! It feels very cumbersome to be forced to either have the Player as SceneObject or reparenting all NetworkObject when spawning the Player, making a task to give the player a weapon more difficult and tideous than it should be.
Totally agree with @herrmutig. Kinda defeats the purpose of a prefab if you have to manually reassemble a player on the fly. I also don't see the point why we are forced to parent directly under a NetworkObject instead of just mandating a NetworkObject in the root.
Any updates on this? this should be way more prioritized!
The issue here is that the Unity engine doesn't really make this feasible. The reason we need the parent to be a NetworkObject (or the scene root) is that those are the only things you can reliably create an ADDRESS for.
For other objects, the instance IDs are runtime-dependant and won't match between a server and client or two clients. A hierarchy-based solution is also untenable as there's no consistent way to say "Scene->Player->Arm->Hand" when there may be more than 1 "Player" under Scene or "Arm" under player, for example.
Common approaches around this involve having the server just move the objects in tandem, having a placeholder "reference" object when something is being held, etc, but not actually changing the scene/object hierarchy. Depending on the object in question it may also work for your game to have a non-networked version of the object which you instantiate & parent while it's being held/mounted/etc.
Common approaches around this involve having the server just move the objects in tandem, having a placeholder "reference" object when something is being held, etc, but not actually changing the scene/object hierarchy.
This is indeed how I now handle it: I parent to the player root (which is a networkobject) and then update the localTransform each frame to make it seem like it is parented to e.g. the player hand. A bit cumbersome, but it works, as long as you ensure the authority is the same.
Something I just learned today that helped solve this problem for me:
you can actually simulate the behavior of childing an object to a parent using the existing component "Parent Constraint"