com.unity.netcode.gameobjects
com.unity.netcode.gameobjects copied to clipboard
Despawn/Spawn functionality seems to be broken after removing Prefabhash functionality
Describe the bug
It seems NetworkObjects used to have the option to manually assign a hash in a field called PrefabHash that was used to associate the hash with the prefab. This was removed.
NetworkObject now auto-generate the hash in a key called GlobalObjectIdHash based on some internal Unity3d object name.
This causes the functionality as described by the docs of calling networkObject.Despawn(false) then networkObject.Spawn() to be broken:
To despawn a networked object on all clients but keep it on the server call NetworkObject.Despawn on the server. An despawned object can also later be spawned again with another spawn call if needed.
This is because when the object is spawned client-side, a new unconfigurable hash is generated for the newly spawned object. However it cannot be known beforehand (from my understanding) what that hash will be, meaning it can't be mapped to in the NetworkManager before-hand, causing the following error when spawned on the client again:

Note that I do have the prefab registered in the networkmanager.
To Reproduce Steps to reproduce the behavior:
- Put a prefab in the scene with a networkobject script attached
- Register that prefab in the networkmanager
- On the server, call
networkObject.Despawn(destroy=false)on it. - On the server, call
networkObject.Spawn()on it.
Actual outcome On the server, the object will be respawned. On the client, the above error will occur since the client-to-be-spawned object will have a new hash that is not mapped to anything in the networkmanager.
Expected outcome The object should be spawned on the client.
Ideally, we have some sort of prefab hash override option on NetworkObject that I can set to a specific value, and assign that value to a prefab in the NetworkManager.
.
Environment (please complete the following information):
- OS: Windows 10
- Unity Version: 2020.3.18f1
- Netcode Version: v1
- Netcode Commit: latest
Additional context Please let me know if:
- I have misunderstood despawn/spawn, network prefabs, etc
- If attaching a sample project will help here.
Thank you!
Hi @Shivang44, With v1.x Netcode for GameObjects (NGO), there is a bit of a trick with respawning what we refer to "in-scene placed NetworkObjects" (whether it is a prefab or just a GameObject with a NetworkObject component added to the scene within the editor). The path of least resistance would be:
- create an in-scene placed NetworkObject (GameObject with a NetworkObject component)
- add a NetworkBehaviour derived component that contains a property of type GameObject (for this we can call it m_ObjectToSpawn) to this component.
- create a network prefab and register it in the NetworkManager NetworkPrefabs list
- assign the prefab to the m_ObjectToSpawn property of your in-scene placed NetworkObject
- Once the in-scene placed NetworkObject has spawned (i.e. OnNetworkSpawn) you can then instantiate an instance of the m_ObjectToSpawn, get the new instance's NetworkObject, and call Spawn on that.
- You can then despawn and respawn that instance as many times as you like.
To do this the way you described in your posted issue above you will have to approach this a little differently as in-scene placed NetworkObjects' GlobalObjectId values are handled slightly different due to the fact that the loading of the scene instantiates the instance outside of NGO .
To be able to respawn in-scene placed NetworkObjects: (using your steps with modifications)
- Put a prefab in the scene with a networkobject script attached
- select the prefab instance and copy the GlobalObjectId value of the prefab instance (in the scene)

- Register the original prefab in the networkmanager
- Click the "Override" check box in that new NetworkPrefab registration entry
- Upon doing this, you will see two options (Prefab|Hash) select hash
- In the field to the right, you will see a numeric field. Paste the GlobalObjectId value you copied in step 2
- For the overriding prefab field, drag and drop the original prefab into that field
It should look like the above image - On the server, call networkObject.Despawn(destroy=false) on it.
- On the server, call networkObject.Spawn() on it.
To better understand the "why" behind this, each in-scene placed NetworkObject will be assigned a unique GlobalObjectId hash value (whether it is a prefab or just a GameObject with a NetworkObject component). Because of this, the GlobalObjectId hash value of an in-scene placed Network Prefab instance will have a unique GlobalObjectId hash value that is different from the original Network Prefab that is registered with the NetworkManager. In order to re-spawn a despawned this instance, you need to link the new GlobalObjectId hash value to the original Network Prefab so the client will know which prefab to spawn.
Since respawning in-scene placed NetworkObjects will still result in a new instance being created on the client side, you might look into Object Pooling as it provides some additional control over the re-use of NetworkObjects on both the client and the server. To see working examples of this, you can clone the Netcode for GameObjects repository which will provide you with the additional testpoject that has a bunch of examples and scripts you can look at. In particular, you might look at the SceneTransitioningAdditive example that demonstrates both additive scene loading and NetworkObject pooling.

Let me know if any of these suggestions help you?
Best Regards,
Noel