Skip to content

Commit f5a3b7d

Browse files
committed
Add network prefab handler documentation
1 parent 0e04623 commit f5a3b7d

File tree

3 files changed

+149
-13
lines changed

3 files changed

+149
-13
lines changed

com.unity.netcode.gameobjects/Documentation~/TableOfContents.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* [Ownership race conditions](basics/race-conditions.md)
3535
* [Spawning and despawning](spawn-despawn.md)
3636
* [Object spawning](basics/object-spawning.md)
37+
* [Network prefab handler](advanced-topics/network-prefab-handler.md)
3738
* [Object pooling](advanced-topics/object-pooling.md)
3839
* [Object visibility](basics/object-visibility.md)
3940
* [Spawning synchronization](basics/spawning-synchronization.md)
@@ -100,4 +101,4 @@
100101
* [NetworkObject parenting](samples/bossroom/networkobject-parenting.md)
101102
* [Optimizing Boss Room](samples/bossroom/optimizing-bossroom.md)
102103
* [NetworkRigidbody](samples/bossroom/networkrigidbody.md)
103-
* [Spawn NetworkObjects](samples/bossroom/spawn-networkobjects.md)
104+
* [Spawn NetworkObjects](samples/bossroom/spawn-networkobjects.md)
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Network prefab handler
2+
3+
The network prefab handler system provides advanced control over how network prefabs are instantiated and destroyed during runtime. This allows overriding the default Netcode for GameObjects [object spawning](../basics/object-spawning.md) behavior by implementing custom prefab handlers.
4+
5+
The network prefab handler system is accessible from the [NetworkManager](../components/networkmanager.md) as `NetworkManager.PrefabHandler`.
6+
7+
## Overview
8+
9+
For an overview of the default object spawning behavior, see the [object spawning](../basics/object-spawning.md) page. The default spawning behavior should cover the majority of spawning use cases, however there are scenarios where you may need more control:
10+
11+
- **Object pooling**: Reusing objects to reduce memory allocation and initialization costs.
12+
- **Performance optimization**: Using different prefab variants on different platforms (e.g. using a simpler object for server simulation).
13+
- **Custom initialization**: Setting up objects with game client specific data or configurations.
14+
- **Conditional spawning**: Initializing different prefab variants based on runtime conditions.
15+
16+
The prefab handler system addresses these needs through a interface-based architecture. The system relies on two key methods, `Instantiate` and `Destroy`. `Instantiate` is called on non-authority clients when an [authority](../terms-concepts/authority.md) spawns a new [NetworkObject](../basics/networkobject.md) that has a registered network prefab handler. `Destroy` is called on all game clients whenever a registered [NetworkObject](../basics/networkobject.md) is destroyed.
17+
18+
## Creating a prefab handler
19+
20+
Prefab handlers are classes which implement on of the Netcode for GameObjects prefab handler descriptions. There are currently two such descriptions:
21+
22+
- **INetworkPrefabInstanceHandler**: This is the simplest interface for custom prefab handlers.
23+
- **NetworkPrefabInstanceHandlerWithData**: This specialized handler receives custom data from the authority during spawning, enabling dynamic prefab customization.
24+
25+
Netcode will use the `Instantiate` and `Destroy` methods in place of default spawn handlers for the `NetworkObject` used during spawning and despawning. Because the message to instantiate a new `NetworkObject` originates from the [authority](../terms-concepts/authority.md), not all game clients will have the Instantiate method. All non-authority clients will have the instantiate method invoked if the `INetworkPrefabInstanceHandler` implementation is registered with `NetworkPrefabHandler` (`NetworkManager.PrefabHandler`) and the authority spawns the registered/associated `NetworkObject`.
26+
27+
### INetworkPrefabInstanceHandler
28+
29+
This is the simplest prefab handler description. Use the `INetworkPrefabInstanceHandler` for situations where the prefab override behaviour is consistent and known.
30+
31+
```csharp
32+
public interface INetworkPrefabInstanceHandler
33+
{
34+
NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation);
35+
void Destroy(NetworkObject networkObject);
36+
}
37+
```
38+
39+
### NetworkPrefabInstanceHandlerWithData
40+
41+
the `NetworkPrefabInstanceHandlerWithData` allows for sending custom data from the authority during object spawning. This extra data can then be used to change the behavior of the `Instantiate` method. An implementation of `NetworkPrefabInstanceHandlerWithData` allows for sending any custom type that is serializable using [INetworkSerializable](advanced-topics/serialization/inetworkserializable.md).
42+
43+
```csharp
44+
public abstract class NetworkPrefabInstanceHandlerWithData<T> : INetworkPrefabInstanceHandlerWithData
45+
where T : struct, INetworkSerializable
46+
{
47+
public abstract NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation, T instantiationData);
48+
public abstract void Destroy(NetworkObject networkObject);
49+
}
50+
```
51+
52+
## Prefab handler registration
53+
54+
Once you have created a class to be your prefab handler, you can then register the class with the network prefab handler system using `NetworkManager.PrefabHandler.AddHandler`. Prefab handlers are registered against a NetworkObject's [GlobalObjectIdHash](../basics/networkobject.md#using-networkobjects).
55+
56+
```csharp
57+
public class GameManager : NetworkBehaviour
58+
{
59+
[SerializeField] private GameObject prefabToSpawn;
60+
61+
void Start()
62+
{
63+
var customHandler = new MyPrefabHandler();
64+
NetworkManager.PrefabHandler.AddHandler(prefabToSpawn, customHandler);
65+
}
66+
}
67+
```
68+
69+
Prefab handlers can be unregistered using `NetworkManager.PrefabHandler.RemoveHandler`.
70+
71+
## Object spawning with prefab handlers
72+
73+
Once a prefab handler is registered Netcode will automatically use the defined `Initialize` and `Destroy` methods to manage the object lifecycle. [Spawn the network prefab as usual](../basics/object-spawning.md#spawning-a-network-prefab-overview) and the `Initialize` method will be called on whichever handler is registered with the spawned network prefab.
74+
75+
Note that the `Initialize` method is only called on non-authority clients. To customize network prefab behavior on the authority, you can use [prefab overrides](../basics/object-spawning.md#taking-prefab-overrides-into-consideration).
76+
77+
### Object spawning with custom data
78+
79+
For handlers that support custom data, the data to send needs to be manually set. To do this, call `SetInstantiationData` before calling the `Spawn` method. If `SetInstantiationData` is not called, the `default` implementation will be sent to the `Instantiate` call.
80+
81+
```csharp
82+
public struct SpawnData : INetworkSerializable
83+
{
84+
public int version;
85+
public string name;
86+
87+
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
88+
{
89+
serializer.SerializeValue(ref version);
90+
serializer.SerializeValue(ref name);
91+
}
92+
}
93+
94+
public class CountingObject : NetworkBehaviour
95+
{
96+
[SerializeField] private GameObject prefabToSpawn;
97+
public string currentName
98+
99+
public void SpawnObject(int objectTypeToSpawn)
100+
{
101+
var instance = Instantiate(prefabToSpawn);
102+
103+
// Set data before spawning
104+
var customSpawnData = new SpawnData { version: objectTypeToSpawn, name: currentName}
105+
NetworkManager.Singleton.PrefabHandler.SetInstantiationData(instance, customSpawnData);
106+
107+
instance.Spawn();
108+
}
109+
}
110+
```
111+
112+
All non-authority clients will then receive this data when `Instantiate` is called.
113+
114+
```csharp
115+
public class SpawnWithDataSystem : NetworkPrefabInstanceHandlerWithData<SpawnData>
116+
{
117+
public override NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation, SpawnData data)
118+
{
119+
// Create the client-side prefab using the spawn data from the authority
120+
var prefabToSpawn = GetPrefabForVersion(data.version);
121+
var instance = Instantiate(prefabToSpawn);
122+
123+
var obj = instance.GetComponent<CountingObject>();
124+
obj.currentName = data.name;
125+
126+
return instance.GetComponent<NetworkObject>();
127+
}
128+
129+
public override void Destroy(NetworkObject networkObject)
130+
{
131+
Object.DestroyImmediate(networkObject.gameObject);
132+
}
133+
134+
private GameObject GetPrefabForVersion(int version)
135+
{
136+
// Here you can implement logic to return a different client-side game object
137+
// depending on the information sent from the server.
138+
}
139+
}
140+
```
141+
142+
## Further Reading
143+
144+
- [Object pooling](./object-pooling.md)
145+
- [Authority prefab overrides](../basics/object-spawning.md#taking-prefab-overrides-into-consideration)

com.unity.netcode.gameobjects/Documentation~/advanced-topics/object-pooling.md

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,7 @@ Netcode for GameObjects (Netcode) provides built-in support for Object Pooling,
44

55
See [Introduction to Object Pooling](https://learn.unity.com/tutorial/introduction-to-object-pooling) to learn more about the importance of pooling objects.
66

7-
## NetworkPrefabInstanceHandler
8-
9-
You can register your own spawn handlers by including the `INetworkPrefabInstanceHandler` interface and registering with the `NetworkPrefabHandler`.
10-
```csharp
11-
public interface INetworkPrefabInstanceHandler
12-
{
13-
NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation);
14-
void Destroy(NetworkObject networkObject);
15-
}
16-
```
17-
Netcode will use the `Instantiate` and `Destroy` methods in place of default spawn handlers for the `NetworkObject` used during spawning and despawning. Because the message to instantiate a new `NetworkObject` originates from a Host or Server, both won't have the Instantiate method invoked. All clients (excluding a Host) will have the instantiate method invoked if the `INetworkPrefabInstanceHandler` implementation is registered with `NetworkPrefabHandler` (`NetworkManager.PrefabHandler`) and a Host or Server spawns the registered/associated `NetworkObject`.
7+
To learn how to override the default Netcode destroy and spawn handlers, see the [Network prefab handler](./network-prefab-handler.md).
188

199
<!-- Commenting this out until we can get external code references working
2010
@@ -26,4 +16,4 @@ https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop/blob/v2
2616
2717
Let's have a look at `NetworkObjectPool` first. `PooledPrefabsList` has a list of prefabs to handle, with an initial number of instances to spawn for each. The `RegisterPrefabInternal` method, called in `OnNetworkSpawn`, initializes the different pools for each Prefab as `ObjectPool`s inside the `m_PooledObjects` dictionary. It also instantiates the handlers for each Prefab and registers them. To use these objects, a user then needs to obtain it via the `GetNetworkObject` method before spawning it, then return the object to the pool after use with `ReturnNetworkObject` before despawning it. This only needs to be done on the server, as the `PooledPrefabInstanceHandler` will handle it on the client(s) when the network object's `Spawn` or `Despawn` method is called, via its `Instantiate` and `Destroy` methods. Inside those methods, the `PooledPrefabInstanceHandler` simply calls the pool to get the corresponding object, or to return it.
2818
29-
-->
19+
-->

0 commit comments

Comments
 (0)