DOTSNET icon indicating copy to clipboard operation
DOTSNET copied to clipboard

Spawning a prefab with nested `NetworkIdentity`s results in extra entities client-side and `netId` set to 0

Open HeyZoos opened this issue 4 years ago • 3 comments

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:

  1. Create a fresh unity project and add DOTSNET
  2. Create a prefab with a NetworkIdentity, call it Parent
  3. Create another prefab with a NetworkIdentity and nest it under parent, add a visual representation if you want

Your prefabs should now look like this

image

image

  1. 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

HeyZoos avatar Jun 13 '21 16:06 HeyZoos

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);
                    ```

HeyZoos avatar Jun 13 '21 18:06 HeyZoos

The NetworkIdentitys, when nested end up with the same prefabIds as the parent NetworkIdentity

HeyZoos avatar Jun 13 '21 23:06 HeyZoos

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.

HeyZoos avatar Jun 14 '21 01:06 HeyZoos