Spawning
Introduction
NetworkObjects
cannot be instantiated with the regular GameObject.Instantiate functions instead they have to be spawned.
To spawn a NetworkObject
at runtime use the Runner.Spawn()
method. Scene objects do not need to be spawned they are automatically spawned when the scene is loaded.
The NetworkObject
is used by Fusion to assign a network-wide unique identifier so all clients can agree on which instance is which and correctly synchronize each networked object's state. The Runner.Spawn()
method tells Fusion when and how to add a new object instance to the collective network state.
IMPORTANT!
Do NOT use Unity's built in GameObject.Instantiate()
method for networked object , this will just create a local game object which is completely detached from the Fusion simulation loop with a broken network state.
Runner.Spawn
The Runner.Spawn()
method on the Fusion NetworkRunner
instance mimics the GameObject.Instantiate()
method in Unity. The parameters that can be provided to the method are:
- a prefab of type
NetworkObject
. - a position
- a rotation
- a
PlayerRef
to identify the client with input authority over the object. (Only relevant for Host/Server Mode) - a delegate of type
NetworkRunner.OnBeforeSpawned
to run before replicating the object on the other instances
Only the prefab is a mandatory parameter, all others are optional.
Note: if you pass a position and/or rotation to the Spawn
method it will only affect the object's transform on the peer that spawns it. To see this position and rotation reflected on other peers you can attach a NetworkTransform
, any other component which inherits from NetworkTRSP
or a fully custom component which synchronizes the transform data.
C#
var obj = Runner.Spawn(prefab, Vector3.zero, Quaternion.identity, Runner.LocalPlayer, MyOnBeforeSpawnDelegate);
Although any client can call Runner.Spawn()
, the results will differ depending on the network topology.
- In Host and Server Mode only the Host/Server can spawn
NetworkObjects
. Clients need to send a request to the Host/Server (such as an RPC) to request a spawn instead. - In Shared Mode any client can spawn a
NetworkObject
. Spawning aNetworkObject
automatically assigns StateAuthority over it to the client.
Input Authority
The input authority is assigned to a particular client by passing in their PlayerRef
to the method; this is optional. The client to whom input authority was given will be able to provide input data for the object and (in addition to the Host or Server) is allowed to query that input structure in GetInput()
.
If the object does not require input or no client has input authority over it, null
can be passed instead.
OnBeforeSpawned
The NetworkRunner.OnBeforeSpawned
parameter can take a method or lambda expression matching the delegate signature.
C#
public delegate void OnBeforeSpawned(NetworkRunner runner, NetworkObject obj);
This delegate is invoked after the object is created but before it gets synchronized across all instances. This allows the caller to perform additional custom initialization of the object before any other part of the system is able to access it. This is a good place to initialize custom network properties.
C#
private void MySpawnFunction(){
Runner.Spawn(
_objPrefab,
Vector3.zero,
Quaternion.identity,
inputAuthority: null,
InitializeObjBeforeSpawn,
predictionKey: null
);
}
private void InitializeObjBeforeSpawn(NetworkRunner runner, NetworkObject obj)
{
var objSB = obj.GetComponent<ObjSimulationBehaviour>();
objSB.InitializeObjSettings(_currentExplosionForce);
}
It is also possible to use a lambda expression to have the possibility to pass more parameters.
C#
private void MySpawnFunction(){
Runner.Spawn(
_objPrefab,
Vector3.zero,
Quaternion.identity,
inputAuthority: null,
(Runner, NO) => NO.GetComponent<MyCustomBehaviour>().Init(myInt, myParameter)
predictionKey: null
);
}
Spawned
ISpawned.Spawned()
is called immediately after the NetworkRunner
attaches a NetworkObject
(either as a result of a NetworkRunner.Spawn()
call, or loading a Scene which contained a NetworkObject
). The Spawned()
callback can be considered Fusion's alternative to Awake()
, and is called AFTER the object has been attached and is valid.
NetworkBehaviour
implements the ISpawned
interface with an empty virtual Spawned()
method. To implement Spawned()
for a custom NetworkBehaviour
, simply override Spawned()
.
Any Networked Property values changes made on the State Authority in Spawned()
will be the initial values for all spawned instances of that NetworkObject
on all other peers. HOWEVER, remote peers may not always spawn objects on the same tick as the State Authority (due to Area of Interest, Interest Management, late joining, and Prioritization). When a NetworkObject
spawns remotely on a later tick than the State Authority, it will spawn with the values that the State Authority had for that later tick.
- For spawns on a peer with State Authority,
Spawned()
is called immediately afterRunner.Spawn()
. - For non-State Authority peers, The
NetworkObject
is spawned when theNetworkRunner
receives a network state for anNetworkObject
that does not exist locally.
If a NetworkObject
should be initialized at prior to being attached to the NetworkRunner
, use a pre-spawn OnBeforeSpawned callback supplied to Runner.Spawn()
.
IAfterSpawned
IAfterSpawned.AfterSpawned()
is called after a batch of NetworkObject
s have spawned and have all ISpawned.Spawned()
callbacks have finished. This can be thought of as Fusion's alternative to Start()
. Use this callback when a NetworkBehaviour
needs to get or set values in another NetworkBehaviour
after spawning, without concerns about execution order.
Despawn
To remove a network object, the peer with State Authority over the object may call Runner.Despawn()
.
Despawned
Similar to how Runner.Spawn()
triggers the Spawned()
method call for classes implementing ISpawned
such as NetworkBehaviour
, Despawn()
will result in the Despawned()
method to be called for classes implementing IDespawned
.