Unity Version: 6000.3.13f1
Fish-Net version: 4.6.20
Discord link
Description
When a NetworkObject is spawned with a parent (i.e. when spawning a UI element into a canvas), the parent transform is correctly set for the object spawned on clients, but the NetworkObject parent NetworkBehavior fields are not assigned for the clients. This leads to a warning from NetworkTransform for example: Cursor Party Cursor(Clone) parent was set without calling SetParent. Use networkObject.SetParent(obj) to assign a NetworkObject a new parent. This is being made a requirement in Fish-Networking v4.
Here's a relevant snippet from our spawning logic:
private void SceneManager_OnClientPresenceChangeEnd(ClientPresenceChangeEventArgs args)
{
if (!networkManager.IsServerStarted) return;
if (args.Scene != gameObject.scene) return;
if (!args.Added) return;
...
var nob = networkManager.GetPooledInstantiated(
playerPrefab.NetworkObject, position, rotation, parent, true
);
var networkPlayerObject = nob.GetComponent<NetworkSessionObject>();
if (parent)
{
nob.SetParent(parentNetworkBehaviour);
}
playerObjects.Add(player, networkPlayerObject);
networkManager.ServerManager.Spawn(networkPlayerObject, player);
//If there are no global scenes
if (addOwnerToDefaultScene)
{
networkManager.SceneManager.AddOwnerToDefaultScene(nob);
}
}
In the snippet you can see that we are:
- Spawning the object with the parent transform via
GetPooledInstantiated
- Calling
SetParent to set the parent NetworkBehaviour
- Calling
Spawn after SetParent
After chasing down the issue locally, here's what I think is happening:
- The server uses the code above to spawn and sets the correct parent (Object ID 5)
- The client receives the spawn message and begins spawning the object in
ClientObjectCache.Iterate().
ClientObjectCache.<Iterate>g_ProcessObject() calls ClientObjects.GetInstantiatedNetworkObject(). The cnob.ParentObjectId is 5 here, so we know that the parent was sent to the client.
GetInstanantiatedNetworkObject sets up the parent for the transform but does not set the parent network behavior. ProcessObject() explicitly says "Prenting and transform is done during the instantiation process" in a comment, so it assumes that the parent is set.
- The parent
NetworkBehaviour is never set on the created NetworkObject
- The
NetworkTransform sees that the transform has a parent but the parent NetworkBehaviour is not set and logs a warning.
I think that ProcessObject() needs to call SetParentAndTransformProperties() after creating the NetworkObject (like it does for scene objects). When I do this manually (using my debugger), it does set the parent and resolve the warning.
Replication
- Use the above snippet to spawn a prefab with a
NetworkTransform and a parent NetworkBehaviour for players
- Start hosting and connect a client
- Observe the warning from
NetworkTransform
Expected behavior
The client-side prefab's NetworkObject has the same NetworkBehaviour parent as the server-side object and no warnings are logged.
Unity Version: 6000.3.13f1
Fish-Net version: 4.6.20
Discord link
Description
When a
NetworkObjectis spawned with a parent (i.e. when spawning a UI element into a canvas), the parent transform is correctly set for the object spawned on clients, but theNetworkObjectparentNetworkBehaviorfields are not assigned for the clients. This leads to a warning fromNetworkTransformfor example:Cursor Party Cursor(Clone) parent was set without calling SetParent. Use networkObject.SetParent(obj) to assign a NetworkObject a new parent. This is being made a requirement in Fish-Networking v4.Here's a relevant snippet from our spawning logic:
In the snippet you can see that we are:
GetPooledInstantiatedSetParentto set the parentNetworkBehaviourSpawnafterSetParentAfter chasing down the issue locally, here's what I think is happening:
ClientObjectCache.Iterate().ClientObjectCache.<Iterate>g_ProcessObject()callsClientObjects.GetInstantiatedNetworkObject(). Thecnob.ParentObjectIdis 5 here, so we know that the parent was sent to the client.GetInstanantiatedNetworkObjectsets up the parent for the transform but does not set the parent network behavior.ProcessObject()explicitly says "Prenting and transform is done during the instantiation process" in a comment, so it assumes that the parent is set.NetworkBehaviouris never set on the createdNetworkObjectNetworkTransformsees that the transform has a parent but the parentNetworkBehaviouris not set and logs a warning.I think that
ProcessObject()needs to callSetParentAndTransformProperties()after creating theNetworkObject(like it does for scene objects). When I do this manually (using my debugger), it does set the parent and resolve the warning.Replication
NetworkTransformand a parentNetworkBehaviourfor playersNetworkTransformExpected behavior
The client-side prefab's
NetworkObjecthas the sameNetworkBehaviourparent as the server-side object and no warnings are logged.