Spawning a prefab with nested `NetworkIdentity`s results in extra entities client-side and `netId` set to 0
Describe the bug
Spawning a prefab with nested NetworkIdentitys results in extra entities and no netId to be set.
To Reproduce Steps to reproduce the behavior:
- Create a fresh unity project and add DOTSNET
- Create a prefab with a
NetworkIdentity, call itParent - Create another prefab with a
NetworkIdentityand nest it under parent, add a visual representation if you want
Your prefabs should now look like this


- Trigger a spawn by hooking into one of the existing systems (I hooked into the chat system message server system)
protected override void OnMessage(int connectionId, ChatMessage message)
{
var prefab = _prefabSystem.prefabs.ToList()[0];
for (int i = 0; i < 10; i++)
{
Debug.Log("Hello");
var spawned = EntityManager.Instantiate(prefab.Value);
server.Spawn(spawned, connectionId);
}
...
Expected behavior
Occurs when spawning untested child prefab, only 10 entities spawn client-side and all have unique netId values
Actual behavior
Hundreds of extra client-side entities all with netId set to 0
Desktop (please complete the following information):
- Windows 10
- DOTSNET 1.30
It doesn't look like the Spawn system makes any effort to inspect a prefabs children?
NetworkIdentity identity = GetComponent<NetworkIdentity>(entity);
if (identity.netId == 0)
{
// set netId to Entity's unique id (Index + Version)
// there is no reason to generate a new unique id if we already
// have one. this is way easier to debug as well.
// -> on server, netId is simply the entity.UniqueId()
// -> on client, it's a unique Id from the server
identity.netId = entity.UniqueId();
// set the owner connectionId
identity.connectionId = ownerConnectionId;
// apply component changes
SetComponent(entity, identity);
```
The NetworkIdentitys, when nested end up with the same prefabIds as the parent NetworkIdentity
The issue is here in NetworkIdentityAuthoring.cs:
// is this a prefab? then assign prefab's Guid
if (PrefabUtility.IsPartOfPrefabAsset(gameObject))
{
string path = AssetDatabase.GetAssetPath(gameObject);
AssetDatabase.GetAssetPath(gameObject) will return the same path for both the parent NetworkIdentity component and a nested NetworkIdentity component.
And because these are the same, when the server sends a spawn message, it tells the client to spawn multiple of the parent.