Simulation Behaviour
Overview
SimulationBehaviour
is the base class for any behaviour tied to the Fusion Network Simulation Loop. Any behaviours which are part of or affect the simulation state have to derive from SimulationBehaviour
instead of MonoBehaviour
.
Contrary to a NetworkBehaviour
, a SimulationBehaviour
cannot carry any [Networked]
state. It is therefore ideal for behaviours which need to run based on the Fusion Simulation Loop but do not need to have their own state synchronised.
N.B.: A SimulationBehaviour
can modify the [Networked]
state of a NetworkBehaviour
.
All logic which touches upon either the [Networked]
state of a NetworkBehaviour
or should be executed as part of the Fusion Update Loop has to be implemented in FixedUpdateNetwork()
.
Network Object
All SimulationBehaviour
components can access their associated NetworkObject
via the Object
property.
Spawn and Despawn
To implement the Spawned()
and Despawned()
methods in a SimulationBehaviour
, it needs to implement the ISpawned
and IDespawned
interfaces respectively.
Example
For example, the LevelManager
in the Tanknarok sample spawns powerups. Although powerups are NetworkObject
s, the LevelManager
only has to affect and know of the simulation state to execute its behaviour. Therefore, inheriting from SimulationBehaviour
is the right approach.
C#
public class LevelManager : SimulationBehaviour
{
[SerializeField] private float _powerupDelay;
[SerializeField] private NetworkObject _powerupPrefab;
private TickTimer _powerupTimer;
public override void FixedUpdateNetwork()
{
// All of the level management logic happens server-side, so bail if we're not the server.
if (!Object.HasStateAuthority) return;
// Only active duty of the LevelManager is to spawn powerups whenever the timer expires
if (_powerupTimer.ExpiredOrNotRunning(Runner))
{
// Reset timer, and check if there is a free spot to spawn a new powerup
_powerupTimer = TickTimer.CreateFromSeconds(Runner,_powerupDelay);
SpawnPoint spawnPoint = GetSpawnPoint(SpawnPoint.Type.Powerup);
if (spawnPoint != null)
{
Debug.Log("Spawning Powerup");
NetworkObject powerupobj = Runner.Spawn(_powerupPrefab, spawnPoint.transform.position, spawnPoint.transform.rotation, PlayerRef.None);
powerupobj.GetComponent<Powerup>().Init();
}
else
{
Debug.Log("Not Spawning Powerup - no free spot");
}
}
}
}
If the behaviour needs to hold [Networked]
properties, it has to derive from NetworkBehaviour
instead.