Network Behaviours are the primary way to implement custom multiplayer behavior in Spatial. You create custom network behaviors by inheriting from the SpatialNetworkBehaviour class. A NetworkBehaviour requires a NetworkObject component to be present on the same GameObject or its parent (a behavior needs to be associated with a network object).
SpatialNetworkBehaviour is an abstract class that provides a set of methods and properties to interact with the network system.
Called after the NetworkObject is bound to the network context and is ready to be used. When this is called, all of the behaviours' Network Variables will be initialized and their value can be accessed and modified by the client that has control of it.
Despawned()
Called when the NetworkObject was destroyed and before it will be destroyed locally. The state of the object (such as Network Variables) can still be accessed at this point.
The IOwnershipChanged interface provides a method OnOwnershipChanged(NetworkObjectOwnershipChangedEventArgs args) that is called when the ownership of the object changes.
public class OwnershipChangeLogger : SpatialNetworkBehaviour, IOwnershipChanged
{
public void OnOwnershipChanged(NetworkObjectOwnershipChangedEventArgs args)
The IVariablesChanged interface provides a method OnVariablesChanged(NetworkObjectVariablesChangedEventArgs args) that is called when any network variable on the object changes. This includes variables defined in other behaviours attached to the same object, and any synchronized Visual Scripting variables if used.
public class ExampleBehaviour : SpatialNetworkBehaviour, IVariablesChanged
{
private NetworkVariable<int> _health = new();
public void OnVariablesChanged(NetworkObjectVariablesChangedEventArgs args)
{
// Shows how to check if a specific behaviour variable has changed
if (args.changedVariables.ContainsKey(_health.id))
Spawned() is called after the object is bound to the network context and is ready to be used.
After Spawned() is called, we call the following once if they are implemented. This is useful for initializing the owner logic or the object's visual state if it depends on network variables.
IOwnershipChanged.OnOwnershipChanged()
IVariablesChanged.OnVariablesChanged() called with args.changedVariables containing all variables on the object.
During the lifetime of the object, IVariablesChanged.OnVariablesChanged() and IOwnershipChanged.OnOwnershipChanged() will be called as the object changes state.
Despawned() is called before the object is destroyed.
Behaviours can define synchronized state using NetworkVariable<T> fields or properties. Changes to these variables are automatically synchronized across clients.
Adding additional behaviours to a network object at runtime is not supported because the additional behaviours would not be synchronized across clients. Same goes for destroying behaviours at runtime.