NetworkBehaviour components require the use of specialized structures to be serialized and used with
NetworkObjects use the NetworkObjectReference.
NetworkBehaviours use the NetworkBehaviourReference.
NetworkBehaviours can use
RPCs to synchronize state and send messages over the network. to replicate any netcode aware properties or send/receive RPCs a
GameObject must have a NetworkObject component and at least one
NetworkBehaviour component. A
NetworkBehaviour requires a
NetworkObject component on the same relative
GameObject or on a parent of the
GameObject with the
NetworkBehaviour component assigned to it. If you add a
NetworkBehaviour to a GameObject that does not have a
NetworkObject (or any parent), then Netcode for GameObjects will automatically add a
NetworkObject component to the
GameObject in which the
NetworkBehaviour was added.
NetworkBehaviours can contain RPC methods and
NetworkVariables. When you call an RPC function, the function isn't called locally. Instead a message is sent containing your parameters, the
networkId of the
NetworkObject associated with the same GameObject (or child) that the
NetworkBehaviour is assigned to, and the "index" of the
NetworkBehaviour (that is, a
NetworkObject can have several NetworkBehaviours, the index communicates "which one").
It is important that the
NetworkBehaviours on each
NetworkObject remains the same for the server and any client connected. When using multiple projects, this becomes especially important so the server doesn't try to call a client RPC on a
NetworkBehaviour that might not exist on a specific client type (or set a NetworkVariable, etc).
Pre-Spawn and Monobehaviour Updates
NetworkBehaviours derive from MonoBehaviour, the
LateUpdate methods, if defined, will still be invoked on
NetworkBehaviours even when they're not yet spawned. to "exit early" to avoid executing netcode specific code within the update methods, you can check the local
NetworkBehaviour.IsSpawned flag and return if it isn't yet set like the below example:
private void Update()
// Netcode specific logic below here
OnNetworkSpawn is invoked on each
NetworkBehaviour associatd with a
NetworkObject spawned. This is where all netcode related initialization should occur.
You can still use
Start to do things like finding components and assigning them to local properties, but if
NetworkBehaviour.IsSpawned is false don't expect netcode distinguishing properties (like IsClient, IsServer, IsHost, etc) to be accurate while within the those two methods (Awake and Start).
For reference purposes, below is a table of when
NetworkBehaviour.OnNetworkSpawn is invoked relative to the
|Dynamically Spawned||In-Scene Placed|
Dynamically Spawned NetworkObjects
For dynamically spawned
NetworkObjects (instantiating a network Prefab during runtime) the
OnNetworkSpawn method is invoked before the
Start method is invoked. So, it's important to be aware of this because finding and assigning components to a local property within the
Start method exclusively will result in that property not being set in a
OnNetworkSpawn method when the
NetworkObject is dynamically spawned. To circumvent this issue, you can have a common method that initializes the components and is invoked both during the
Start method and the
OnNetworkSpawned method like the code example below:
public class MyNetworkBehaviour : NetworkBehaviour
private MeshRenderer m_MeshRenderer;
private void Start()
private void Initialize()
if (m_MeshRenderer == null)
m_MeshRenderer = FindObjectOfType<MeshRenderer>();
public override void OnNetworkSpawn()
// Do things with m_MeshRenderer
In-Scene Placed NetworkObjects
For in-scene placed
OnNetworkSpawn method is invoked after the
Start method since the SceneManager scene loading process controls when the
NetworkObjects are instantiated. The previous code example shows how one can design a
NetworkBehaviour that assures both in-scene placed and dynamically spawned
NetworkObjects will have assigned the required properties before attempting to access them. Of course, you can always make the decision to have in-scene placed
NetworkObjects contain unique components to that of dynamically spawned
NetworkObjects. It all depends upon what usage pattern works best for your project.
OnNetworkDespawn is invoked on each
NetworkBehaviour associated with a
NetworkObject when it's de-spawned. This is where all netcode "despawn cleanup code" should occur, but isn't to be confused with destroying. Despawning occurs before anything is destroyed.
Each 'NetworkBehaviour' has a virtual 'OnDestroy' method that can be overridden to handle clean up that needs to occur when you know the
NetworkBehaviour is being destroyed.
If you override the virtual 'OnDestroy' method it's important to alway invoke the base like such:
public override void OnDestroy()
// Clean up your NetworkBehaviour
// Always invoked the base
NetworkBehaviour handles other destroy clean up tasks and requires that you invoke the base
OnDestroy method to operate properly.